LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDE2IEZ1bmRhY2nzbiBUZWNuYWxpYSBSZXNlYXJjaCAmIElubm92YXRpb24uCiAqCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCiAqCiAqIENvbnRyaWJ1dG9yczoKICogICBIdWFzY2FyIEVzcGlub3phIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgQWxlamFuZHJhIFJ17XogLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICBJZG95YSBEZWwgUu1vIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgTWFyaSBDYXJtZW4gUGFsYWNpb3MgLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICBBbmdlbCBM83BleiAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoKICogCiAqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5kaWFncmFtLnByb3ZpZGVyczsKCmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwoKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JQWRhcHRhYmxlOwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVjb3JlLkVBbm5vdGF0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVjb3JlLkVPYmplY3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWNvcmUuRWNvcmVGYWN0b3J5OwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLnRyYW5zYWN0aW9uLnV0aWwuVHJhbnNhY3Rpb25VdGlsOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuY29tbW9uLmNvcmUuc2VydmljZS5BYnN0cmFjdFByb3ZpZGVyOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuY29tbW9uLmNvcmUuc2VydmljZS5JT3BlcmF0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuZGlhZ3JhbS5jb3JlLnByZWZlcmVuY2VzLlByZWZlcmVuY2VzSGludDsKaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLmRpYWdyYW0uY29yZS5wcm92aWRlcnMuSVZpZXdQcm92aWRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLmRpYWdyYW0uY29yZS5zZXJ2aWNlcy52aWV3LkNyZWF0ZURpYWdyYW1WaWV3T3BlcmF0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuZGlhZ3JhbS5jb3JlLnNlcnZpY2VzLnZpZXcuQ3JlYXRlRWRnZVZpZXdPcGVyYXRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5kaWFncmFtLmNvcmUuc2VydmljZXMudmlldy5DcmVhdGVOb2RlVmlld09wZXJhdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLmRpYWdyYW0uY29yZS5zZXJ2aWNlcy52aWV3LkNyZWF0ZVZpZXdGb3JLaW5kT3BlcmF0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuZGlhZ3JhbS5jb3JlLnNlcnZpY2VzLnZpZXcuQ3JlYXRlVmlld09wZXJhdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLmRpYWdyYW0uY29yZS51dGlsLlZpZXdVdGlsOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuZGlhZ3JhbS51aS5wcmVmZXJlbmNlcy5JUHJlZmVyZW5jZUNvbnN0YW50czsKaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLmRyYXcyZC51aS5maWd1cmVzLkZpZ3VyZVV0aWxpdGllczsKaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLmVtZi5jb3JlLnV0aWwuRU1GQ29yZVV0aWw7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5lbWYudHlwZS5jb3JlLklFbGVtZW50VHlwZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLmVtZi50eXBlLmNvcmUuSUhpbnRlZFR5cGU7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5ub3RhdGlvbi5Db25uZWN0b3I7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5ub3RhdGlvbi5EZWNvcmF0aW9uTm9kZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLm5vdGF0aW9uLkRpYWdyYW07CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5ub3RhdGlvbi5FZGdlOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUubm90YXRpb24uRm9udFN0eWxlOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUubm90YXRpb24uTG9jYXRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5ub3RhdGlvbi5NZWFzdXJlbWVudFVuaXQ7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5ub3RhdGlvbi5Ob2RlOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUubm90YXRpb24uTm90YXRpb25GYWN0b3J5OwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUubm90YXRpb24uTm90YXRpb25QYWNrYWdlOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUubm90YXRpb24uUmVsYXRpdmVCZW5kcG9pbnRzOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUubm90YXRpb24uUm91dGluZzsKaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLm5vdGF0aW9uLlNoYXBlOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUubm90YXRpb24uVGl0bGVTdHlsZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLm5vdGF0aW9uLlZpZXc7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5ub3RhdGlvbi5kYXRhdHlwZS5SZWxhdGl2ZUJlbmRwb2ludDsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnByZWZlcmVuY2UuSVByZWZlcmVuY2VTdG9yZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnByZWZlcmVuY2UuUHJlZmVyZW5jZUNvbnZlcnRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuRm9udERhdGE7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5hcG0uYmFzZWxpbmUuYmFzZWxpbmUuZGlhZ3JhbS5lZGl0LnBhcnRzLkJhc2VBY3Rpdml0eTJFZGl0UGFydDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5kaWFncmFtLmVkaXQucGFydHMuQmFzZUFjdGl2aXR5QmFzZUFjdGl2aXR5U3ViQWN0aXZpdHlDb21wYXJ0bWVudDJFZGl0UGFydDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5kaWFncmFtLmVkaXQucGFydHMuQmFzZUFjdGl2aXR5QmFzZUFjdGl2aXR5U3ViQWN0aXZpdHlDb21wYXJ0bWVudEVkaXRQYXJ0OwppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQuYXBtLmJhc2VsaW5lLmJhc2VsaW5lLmRpYWdyYW0uZWRpdC5wYXJ0cy5CYXNlQWN0aXZpdHlFZGl0UGFydDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5kaWFncmFtLmVkaXQucGFydHMuQmFzZUFjdGl2aXR5TmFtZTJFZGl0UGFydDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5kaWFncmFtLmVkaXQucGFydHMuQmFzZUFjdGl2aXR5TmFtZUVkaXRQYXJ0OwppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQuYXBtLmJhc2VsaW5lLmJhc2VsaW5lLmRpYWdyYW0uZWRpdC5wYXJ0cy5CYXNlQWN0aXZpdHlQcmVjZWRpbmdBY3Rpdml0eUVkaXRQYXJ0OwppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQuYXBtLmJhc2VsaW5lLmJhc2VsaW5lLmRpYWdyYW0uZWRpdC5wYXJ0cy5CYXNlQWN0aXZpdHlQcm9kdWNlZEFydGVmYWN0RWRpdFBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5hcG0uYmFzZWxpbmUuYmFzZWxpbmUuZGlhZ3JhbS5lZGl0LnBhcnRzLkJhc2VBY3Rpdml0eVJlcXVpcmVkQXJ0ZWZhY3RFZGl0UGFydDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5kaWFncmFtLmVkaXQucGFydHMuQmFzZUFjdGl2aXR5Um9sZUVkaXRQYXJ0OwppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQuYXBtLmJhc2VsaW5lLmJhc2VsaW5lLmRpYWdyYW0uZWRpdC5wYXJ0cy5CYXNlQXJ0ZWZhY3RFZGl0UGFydDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5kaWFncmFtLmVkaXQucGFydHMuQmFzZUFydGVmYWN0TmFtZUVkaXRQYXJ0OwppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQuYXBtLmJhc2VsaW5lLmJhc2VsaW5lLmRpYWdyYW0uZWRpdC5wYXJ0cy5CYXNlRnJhbWV3b3JrRWRpdFBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5hcG0uYmFzZWxpbmUuYmFzZWxpbmUuZGlhZ3JhbS5lZGl0LnBhcnRzLkJhc2VSb2xlRWRpdFBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5hcG0uYmFzZWxpbmUuYmFzZWxpbmUuZGlhZ3JhbS5lZGl0LnBhcnRzLkJhc2VSb2xlTGFiZWxFZGl0UGFydDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5kaWFncmFtLmVkaXQucGFydHMuQmFzZVJvbGVOYW1lRWRpdFBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5hcG0uYmFzZWxpbmUuYmFzZWxpbmUuZGlhZ3JhbS5lZGl0LnBhcnRzLldyYXBwaW5nTGFiZWwyRWRpdFBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5hcG0uYmFzZWxpbmUuYmFzZWxpbmUuZGlhZ3JhbS5lZGl0LnBhcnRzLldyYXBwaW5nTGFiZWwzRWRpdFBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5hcG0uYmFzZWxpbmUuYmFzZWxpbmUuZGlhZ3JhbS5lZGl0LnBhcnRzLldyYXBwaW5nTGFiZWxFZGl0UGFydDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5kaWFncmFtLnBhcnQuQmFzZWxpbmVWaXN1YWxJRFJlZ2lzdHJ5OwoKLyoqCiAqIEBnZW5lcmF0ZWQKICovCnB1YmxpYyBjbGFzcyBCYXNlbGluZVZpZXdQcm92aWRlciBleHRlbmRzIEFic3RyYWN0UHJvdmlkZXIgaW1wbGVtZW50cwoJCUlWaWV3UHJvdmlkZXIgewoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwdWJsaWMgZmluYWwgYm9vbGVhbiBwcm92aWRlcyhJT3BlcmF0aW9uIG9wZXJhdGlvbikgewoJCWlmIChvcGVyYXRpb24gaW5zdGFuY2VvZiBDcmVhdGVWaWV3Rm9yS2luZE9wZXJhdGlvbikgewoJCQlyZXR1cm4gcHJvdmlkZXMoKENyZWF0ZVZpZXdGb3JLaW5kT3BlcmF0aW9uKSBvcGVyYXRpb24pOwoJCX0KCQlhc3NlcnQgb3BlcmF0aW9uIGluc3RhbmNlb2YgQ3JlYXRlVmlld09wZXJhdGlvbjsKCQlpZiAob3BlcmF0aW9uIGluc3RhbmNlb2YgQ3JlYXRlRGlhZ3JhbVZpZXdPcGVyYXRpb24pIHsKCQkJcmV0dXJuIHByb3ZpZGVzKChDcmVhdGVEaWFncmFtVmlld09wZXJhdGlvbikgb3BlcmF0aW9uKTsKCQl9IGVsc2UgaWYgKG9wZXJhdGlvbiBpbnN0YW5jZW9mIENyZWF0ZUVkZ2VWaWV3T3BlcmF0aW9uKSB7CgkJCXJldHVybiBwcm92aWRlcygoQ3JlYXRlRWRnZVZpZXdPcGVyYXRpb24pIG9wZXJhdGlvbik7CgkJfSBlbHNlIGlmIChvcGVyYXRpb24gaW5zdGFuY2VvZiBDcmVhdGVOb2RlVmlld09wZXJhdGlvbikgewoJCQlyZXR1cm4gcHJvdmlkZXMoKENyZWF0ZU5vZGVWaWV3T3BlcmF0aW9uKSBvcGVyYXRpb24pOwoJCX0KCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXByb3RlY3RlZCBib29sZWFuIHByb3ZpZGVzKENyZWF0ZVZpZXdGb3JLaW5kT3BlcmF0aW9uIG9wKSB7CgkJLyoKCQkgaWYgKG9wLmdldFZpZXdLaW5kKCkgPT0gTm9kZS5jbGFzcykKCQkgcmV0dXJuIGdldE5vZGVWaWV3Q2xhc3Mob3AuZ2V0U2VtYW50aWNBZGFwdGVyKCksIG9wLmdldENvbnRhaW5lclZpZXcoKSwgb3AuZ2V0U2VtYW50aWNIaW50KCkpICE9IG51bGw7CgkJIGlmIChvcC5nZXRWaWV3S2luZCgpID09IEVkZ2UuY2xhc3MpCgkJIHJldHVybiBnZXRFZGdlVmlld0NsYXNzKG9wLmdldFNlbWFudGljQWRhcHRlcigpLCBvcC5nZXRDb250YWluZXJWaWV3KCksIG9wLmdldFNlbWFudGljSGludCgpKSAhPSBudWxsOwoJCSAqLwoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwcm90ZWN0ZWQgYm9vbGVhbiBwcm92aWRlcyhDcmVhdGVEaWFncmFtVmlld09wZXJhdGlvbiBvcCkgewoJCXJldHVybiBCYXNlRnJhbWV3b3JrRWRpdFBhcnQuTU9ERUxfSUQuZXF1YWxzKG9wLmdldFNlbWFudGljSGludCgpKQoJCQkJJiYgQmFzZWxpbmVWaXN1YWxJRFJlZ2lzdHJ5CgkJCQkJCS5nZXREaWFncmFtVmlzdWFsSUQoZ2V0U2VtYW50aWNFbGVtZW50KG9wCgkJCQkJCQkJLmdldFNlbWFudGljQWRhcHRlcigpKSkgIT0gLTE7Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXByb3RlY3RlZCBib29sZWFuIHByb3ZpZGVzKENyZWF0ZU5vZGVWaWV3T3BlcmF0aW9uIG9wKSB7CgkJaWYgKG9wLmdldENvbnRhaW5lclZpZXcoKSA9PSBudWxsKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJSUVsZW1lbnRUeXBlIGVsZW1lbnRUeXBlID0gZ2V0U2VtYW50aWNFbGVtZW50VHlwZShvcAoJCQkJLmdldFNlbWFudGljQWRhcHRlcigpKTsKCQlFT2JqZWN0IGRvbWFpbkVsZW1lbnQgPSBnZXRTZW1hbnRpY0VsZW1lbnQob3AuZ2V0U2VtYW50aWNBZGFwdGVyKCkpOwoJCWludCB2aXN1YWxJRDsKCQlpZiAob3AuZ2V0U2VtYW50aWNIaW50KCkgPT0gbnVsbCkgewoJCQkvLyBTZW1hbnRpYyBoaW50IGlzIG5vdCBzcGVjaWZpZWQuIENhbiBiZSBhIHJlc3VsdCBvZiBjYWxsIGZyb20gQ2Fub25pY2FsRWRpdFBvbGljeS4KCQkJLy8gSW4gdGhpcyBzaXR1YXRpb24gdGhlcmUgc2hvdWxkIGJlIE5PIGVsZW1lbnRUeXBlLCB2aXN1YWxJRCB3aWxsIGJlIGRldGVybWluZWQKCQkJLy8gYnkgVmlzdWFsSURSZWdpc3RyeS5nZXROb2RlVmlzdWFsSUQoKSBmb3IgZG9tYWluRWxlbWVudC4KCQkJaWYgKGVsZW1lbnRUeXBlICE9IG51bGwgfHwgZG9tYWluRWxlbWVudCA9PSBudWxsKSB7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQkJdmlzdWFsSUQgPSBCYXNlbGluZVZpc3VhbElEUmVnaXN0cnkuZ2V0Tm9kZVZpc3VhbElEKAoJCQkJCW9wLmdldENvbnRhaW5lclZpZXcoKSwgZG9tYWluRWxlbWVudCk7CgkJfSBlbHNlIHsKCQkJdmlzdWFsSUQgPSBCYXNlbGluZVZpc3VhbElEUmVnaXN0cnkuZ2V0VmlzdWFsSUQob3AKCQkJCQkuZ2V0U2VtYW50aWNIaW50KCkpOwoJCQlpZiAoZWxlbWVudFR5cGUgIT0gbnVsbCkgewoJCQkJaWYgKCFCYXNlbGluZUVsZW1lbnRUeXBlcy5pc0tub3duRWxlbWVudFR5cGUoZWxlbWVudFR5cGUpCgkJCQkJCXx8ICghKGVsZW1lbnRUeXBlIGluc3RhbmNlb2YgSUhpbnRlZFR5cGUpKSkgewoJCQkJCXJldHVybiBmYWxzZTsgLy8gZm9yZWlnbiBlbGVtZW50IHR5cGUKCQkJCX0KCQkJCVN0cmluZyBlbGVtZW50VHlwZUhpbnQgPSAoKElIaW50ZWRUeXBlKSBlbGVtZW50VHlwZSkKCQkJCQkJLmdldFNlbWFudGljSGludCgpOwoJCQkJaWYgKCFvcC5nZXRTZW1hbnRpY0hpbnQoKS5lcXVhbHMoZWxlbWVudFR5cGVIaW50KSkgewoJCQkJCXJldHVybiBmYWxzZTsgLy8gaWYgc2VtYW50aWMgaGludCBpcyBzcGVjaWZpZWQgaXQgc2hvdWxkIGJlIHRoZSBzYW1lIGFzIGluIGVsZW1lbnQgdHlwZQoJCQkJfQoJCQkJaWYgKGRvbWFpbkVsZW1lbnQgIT0gbnVsbAoJCQkJCQkmJiB2aXN1YWxJRCAhPSBCYXNlbGluZVZpc3VhbElEUmVnaXN0cnkKCQkJCQkJCQkuZ2V0Tm9kZVZpc3VhbElEKG9wLmdldENvbnRhaW5lclZpZXcoKSwKCQkJCQkJCQkJCWRvbWFpbkVsZW1lbnQpKSB7CgkJCQkJcmV0dXJuIGZhbHNlOyAvLyB2aXN1YWwgaWQgZm9yIG5vZGUgRUNsYXNzIHNob3VsZCBtYXRjaCB2aXN1YWwgaWQgZnJvbSBlbGVtZW50IHR5cGUKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCWlmICghQmFzZUZyYW1ld29ya0VkaXRQYXJ0Lk1PREVMX0lECgkJCQkJCS5lcXVhbHMoQmFzZWxpbmVWaXN1YWxJRFJlZ2lzdHJ5LmdldE1vZGVsSUQob3AKCQkJCQkJCQkuZ2V0Q29udGFpbmVyVmlldygpKSkpIHsKCQkJCQlyZXR1cm4gZmFsc2U7IC8vIGZvcmVpZ24gZGlhZ3JhbQoJCQkJfQoJCQkJc3dpdGNoICh2aXN1YWxJRCkgewoJCQkJY2FzZSBCYXNlQWN0aXZpdHlFZGl0UGFydC5WSVNVQUxfSUQ6CgkJCQljYXNlIEJhc2VBcnRlZmFjdEVkaXRQYXJ0LlZJU1VBTF9JRDoKCQkJCWNhc2UgQmFzZVJvbGVFZGl0UGFydC5WSVNVQUxfSUQ6CgkJCQljYXNlIEJhc2VBY3Rpdml0eTJFZGl0UGFydC5WSVNVQUxfSUQ6CgkJCQkJaWYgKGRvbWFpbkVsZW1lbnQgPT0gbnVsbAoJCQkJCQkJfHwgdmlzdWFsSUQgIT0gQmFzZWxpbmVWaXN1YWxJRFJlZ2lzdHJ5CgkJCQkJCQkJCS5nZXROb2RlVmlzdWFsSUQob3AuZ2V0Q29udGFpbmVyVmlldygpLAoJCQkJCQkJCQkJCWRvbWFpbkVsZW1lbnQpKSB7CgkJCQkJCXJldHVybiBmYWxzZTsgLy8gdmlzdWFsIGlkIGluIHNlbWFudGljIGhpbnQgc2hvdWxkIG1hdGNoIHZpc3VhbCBpZCBmb3IgZG9tYWluIGVsZW1lbnQKCQkJCQl9CgkJCQkJYnJlYWs7CgkJCQlkZWZhdWx0OgoJCQkJCXJldHVybiBmYWxzZTsKCQkJCX0KCQkJfQoJCX0KCQlyZXR1cm4gQmFzZUFjdGl2aXR5RWRpdFBhcnQuVklTVUFMX0lEID09IHZpc3VhbElECgkJCQl8fCBCYXNlQXJ0ZWZhY3RFZGl0UGFydC5WSVNVQUxfSUQgPT0gdmlzdWFsSUQKCQkJCXx8IEJhc2VSb2xlRWRpdFBhcnQuVklTVUFMX0lEID09IHZpc3VhbElECgkJCQl8fCBCYXNlQWN0aXZpdHkyRWRpdFBhcnQuVklTVUFMX0lEID09IHZpc3VhbElEOwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwcm90ZWN0ZWQgYm9vbGVhbiBwcm92aWRlcyhDcmVhdGVFZGdlVmlld09wZXJhdGlvbiBvcCkgewoJCUlFbGVtZW50VHlwZSBlbGVtZW50VHlwZSA9IGdldFNlbWFudGljRWxlbWVudFR5cGUob3AKCQkJCS5nZXRTZW1hbnRpY0FkYXB0ZXIoKSk7CgkJaWYgKCFCYXNlbGluZUVsZW1lbnRUeXBlcy5pc0tub3duRWxlbWVudFR5cGUoZWxlbWVudFR5cGUpCgkJCQl8fCAoIShlbGVtZW50VHlwZSBpbnN0YW5jZW9mIElIaW50ZWRUeXBlKSkpIHsKCQkJcmV0dXJuIGZhbHNlOyAvLyBmb3JlaWduIGVsZW1lbnQgdHlwZQoJCX0KCQlTdHJpbmcgZWxlbWVudFR5cGVIaW50ID0gKChJSGludGVkVHlwZSkgZWxlbWVudFR5cGUpLmdldFNlbWFudGljSGludCgpOwoJCWlmIChlbGVtZW50VHlwZUhpbnQgPT0gbnVsbAoJCQkJfHwgKG9wLmdldFNlbWFudGljSGludCgpICE9IG51bGwgJiYgIWVsZW1lbnRUeXBlSGludC5lcXVhbHMob3AKCQkJCQkJLmdldFNlbWFudGljSGludCgpKSkpIHsKCQkJcmV0dXJuIGZhbHNlOyAvLyBvdXIgaGludCBpcyB2aXN1YWwgaWQgYW5kIG11c3QgYmUgc3BlY2lmaWVkLCBhbmQgaXQgc2hvdWxkIGJlIHRoZSBzYW1lIGFzIGluIGVsZW1lbnQgdHlwZQoJCX0KCQlpbnQgdmlzdWFsSUQgPSBCYXNlbGluZVZpc3VhbElEUmVnaXN0cnkuZ2V0VmlzdWFsSUQoZWxlbWVudFR5cGVIaW50KTsKCQlFT2JqZWN0IGRvbWFpbkVsZW1lbnQgPSBnZXRTZW1hbnRpY0VsZW1lbnQob3AuZ2V0U2VtYW50aWNBZGFwdGVyKCkpOwoJCWlmIChkb21haW5FbGVtZW50ICE9IG51bGwKCQkJCSYmIHZpc3VhbElEICE9IEJhc2VsaW5lVmlzdWFsSURSZWdpc3RyeQoJCQkJCQkuZ2V0TGlua1dpdGhDbGFzc1Zpc3VhbElEKGRvbWFpbkVsZW1lbnQpKSB7CgkJCXJldHVybiBmYWxzZTsgLy8gdmlzdWFsIGlkIGZvciBsaW5rIEVDbGFzcyBzaG91bGQgbWF0Y2ggdmlzdWFsIGlkIGZyb20gZWxlbWVudCB0eXBlCgkJfQoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwdWJsaWMgRGlhZ3JhbSBjcmVhdGVEaWFncmFtKElBZGFwdGFibGUgc2VtYW50aWNBZGFwdGVyLAoJCQlTdHJpbmcgZGlhZ3JhbUtpbmQsIFByZWZlcmVuY2VzSGludCBwcmVmZXJlbmNlc0hpbnQpIHsKCQlEaWFncmFtIGRpYWdyYW0gPSBOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZURpYWdyYW0oKTsKCQlkaWFncmFtLmdldFN0eWxlcygpLmFkZChOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZURpYWdyYW1TdHlsZSgpKTsKCQlkaWFncmFtLnNldFR5cGUoQmFzZUZyYW1ld29ya0VkaXRQYXJ0Lk1PREVMX0lEKTsKCQlkaWFncmFtLnNldEVsZW1lbnQoZ2V0U2VtYW50aWNFbGVtZW50KHNlbWFudGljQWRhcHRlcikpOwoJCWRpYWdyYW0uc2V0TWVhc3VyZW1lbnRVbml0KE1lYXN1cmVtZW50VW5pdC5QSVhFTF9MSVRFUkFMKTsKCQlyZXR1cm4gZGlhZ3JhbTsKCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHVibGljIE5vZGUgY3JlYXRlTm9kZShJQWRhcHRhYmxlIHNlbWFudGljQWRhcHRlciwgVmlldyBjb250YWluZXJWaWV3LAoJCQlTdHJpbmcgc2VtYW50aWNIaW50LCBpbnQgaW5kZXgsIGJvb2xlYW4gcGVyc2lzdGVkLAoJCQlQcmVmZXJlbmNlc0hpbnQgcHJlZmVyZW5jZXNIaW50KSB7CgkJZmluYWwgRU9iamVjdCBkb21haW5FbGVtZW50ID0gZ2V0U2VtYW50aWNFbGVtZW50KHNlbWFudGljQWRhcHRlcik7CgkJZmluYWwgaW50IHZpc3VhbElEOwoJCWlmIChzZW1hbnRpY0hpbnQgPT0gbnVsbCkgewoJCQl2aXN1YWxJRCA9IEJhc2VsaW5lVmlzdWFsSURSZWdpc3RyeS5nZXROb2RlVmlzdWFsSUQoY29udGFpbmVyVmlldywKCQkJCQlkb21haW5FbGVtZW50KTsKCQl9IGVsc2UgewoJCQl2aXN1YWxJRCA9IEJhc2VsaW5lVmlzdWFsSURSZWdpc3RyeS5nZXRWaXN1YWxJRChzZW1hbnRpY0hpbnQpOwoJCX0KCQlzd2l0Y2ggKHZpc3VhbElEKSB7CgkJY2FzZSBCYXNlQWN0aXZpdHlFZGl0UGFydC5WSVNVQUxfSUQ6CgkJCXJldHVybiBjcmVhdGVCYXNlQWN0aXZpdHlfMjAwMShkb21haW5FbGVtZW50LCBjb250YWluZXJWaWV3LCBpbmRleCwKCQkJCQlwZXJzaXN0ZWQsIHByZWZlcmVuY2VzSGludCk7CgkJY2FzZSBCYXNlQXJ0ZWZhY3RFZGl0UGFydC5WSVNVQUxfSUQ6CgkJCXJldHVybiBjcmVhdGVCYXNlQXJ0ZWZhY3RfMjAwMihkb21haW5FbGVtZW50LCBjb250YWluZXJWaWV3LCBpbmRleCwKCQkJCQlwZXJzaXN0ZWQsIHByZWZlcmVuY2VzSGludCk7CgkJY2FzZSBCYXNlUm9sZUVkaXRQYXJ0LlZJU1VBTF9JRDoKCQkJcmV0dXJuIGNyZWF0ZUJhc2VSb2xlXzIwMDMoZG9tYWluRWxlbWVudCwgY29udGFpbmVyVmlldywgaW5kZXgsCgkJCQkJcGVyc2lzdGVkLCBwcmVmZXJlbmNlc0hpbnQpOwoJCWNhc2UgQmFzZUFjdGl2aXR5MkVkaXRQYXJ0LlZJU1VBTF9JRDoKCQkJcmV0dXJuIGNyZWF0ZUJhc2VBY3Rpdml0eV8zMDAxKGRvbWFpbkVsZW1lbnQsIGNvbnRhaW5lclZpZXcsIGluZGV4LAoJCQkJCXBlcnNpc3RlZCwgcHJlZmVyZW5jZXNIaW50KTsKCQl9CgkJLy8gY2FuJ3QgaGFwcGVuLCBwcm92aWRlZCAjcHJvdmlkZXMoQ3JlYXRlTm9kZVZpZXdPcGVyYXRpb24pIGlzIGNvcnJlY3QKCQlyZXR1cm4gbnVsbDsKCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHVibGljIEVkZ2UgY3JlYXRlRWRnZShJQWRhcHRhYmxlIHNlbWFudGljQWRhcHRlciwgVmlldyBjb250YWluZXJWaWV3LAoJCQlTdHJpbmcgc2VtYW50aWNIaW50LCBpbnQgaW5kZXgsIGJvb2xlYW4gcGVyc2lzdGVkLAoJCQlQcmVmZXJlbmNlc0hpbnQgcHJlZmVyZW5jZXNIaW50KSB7CgkJSUVsZW1lbnRUeXBlIGVsZW1lbnRUeXBlID0gZ2V0U2VtYW50aWNFbGVtZW50VHlwZShzZW1hbnRpY0FkYXB0ZXIpOwoJCVN0cmluZyBlbGVtZW50VHlwZUhpbnQgPSAoKElIaW50ZWRUeXBlKSBlbGVtZW50VHlwZSkuZ2V0U2VtYW50aWNIaW50KCk7CgkJc3dpdGNoIChCYXNlbGluZVZpc3VhbElEUmVnaXN0cnkuZ2V0VmlzdWFsSUQoZWxlbWVudFR5cGVIaW50KSkgewoJCWNhc2UgQmFzZUFjdGl2aXR5UmVxdWlyZWRBcnRlZmFjdEVkaXRQYXJ0LlZJU1VBTF9JRDoKCQkJcmV0dXJuIGNyZWF0ZUJhc2VBY3Rpdml0eVJlcXVpcmVkQXJ0ZWZhY3RfNDAwMShjb250YWluZXJWaWV3LAoJCQkJCWluZGV4LCBwZXJzaXN0ZWQsIHByZWZlcmVuY2VzSGludCk7CgkJY2FzZSBCYXNlQWN0aXZpdHlQcm9kdWNlZEFydGVmYWN0RWRpdFBhcnQuVklTVUFMX0lEOgoJCQlyZXR1cm4gY3JlYXRlQmFzZUFjdGl2aXR5UHJvZHVjZWRBcnRlZmFjdF80MDAyKGNvbnRhaW5lclZpZXcsCgkJCQkJaW5kZXgsIHBlcnNpc3RlZCwgcHJlZmVyZW5jZXNIaW50KTsKCQljYXNlIEJhc2VBY3Rpdml0eVByZWNlZGluZ0FjdGl2aXR5RWRpdFBhcnQuVklTVUFMX0lEOgoJCQlyZXR1cm4gY3JlYXRlQmFzZUFjdGl2aXR5UHJlY2VkaW5nQWN0aXZpdHlfNDAwMyhjb250YWluZXJWaWV3LAoJCQkJCWluZGV4LCBwZXJzaXN0ZWQsIHByZWZlcmVuY2VzSGludCk7CgkJY2FzZSBCYXNlQWN0aXZpdHlSb2xlRWRpdFBhcnQuVklTVUFMX0lEOgoJCQlyZXR1cm4gY3JlYXRlQmFzZUFjdGl2aXR5Um9sZV80MDA0KGNvbnRhaW5lclZpZXcsIGluZGV4LCBwZXJzaXN0ZWQsCgkJCQkJcHJlZmVyZW5jZXNIaW50KTsKCQl9CgkJLy8gY2FuIG5ldmVyIGhhcHBlbiwgcHJvdmlkZWQgI3Byb3ZpZGVzKENyZWF0ZUVkZ2VWaWV3T3BlcmF0aW9uKSBpcyBjb3JyZWN0CgkJcmV0dXJuIG51bGw7Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXB1YmxpYyBOb2RlIGNyZWF0ZUJhc2VBY3Rpdml0eV8yMDAxKEVPYmplY3QgZG9tYWluRWxlbWVudCwKCQkJVmlldyBjb250YWluZXJWaWV3LCBpbnQgaW5kZXgsIGJvb2xlYW4gcGVyc2lzdGVkLAoJCQlQcmVmZXJlbmNlc0hpbnQgcHJlZmVyZW5jZXNIaW50KSB7CgkJTm9kZSBub2RlID0gTm90YXRpb25GYWN0b3J5LmVJTlNUQU5DRS5jcmVhdGVOb2RlKCk7CgkJbm9kZS5nZXRTdHlsZXMoKQoJCQkJLmFkZChOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZURlc2NyaXB0aW9uU3R5bGUoKSk7CgkJbm9kZS5nZXRTdHlsZXMoKS5hZGQoTm90YXRpb25GYWN0b3J5LmVJTlNUQU5DRS5jcmVhdGVGb250U3R5bGUoKSk7CgkJbm9kZS5nZXRTdHlsZXMoKS5hZGQoTm90YXRpb25GYWN0b3J5LmVJTlNUQU5DRS5jcmVhdGVGaWxsU3R5bGUoKSk7CgkJbm9kZS5nZXRTdHlsZXMoKS5hZGQoCgkJCQlOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZUhpbnRlZERpYWdyYW1MaW5rU3R5bGUoKSk7CgkJbm9kZS5zZXRMYXlvdXRDb25zdHJhaW50KE5vdGF0aW9uRmFjdG9yeS5lSU5TVEFOQ0UuY3JlYXRlQm91bmRzKCkpOwoJCW5vZGUuc2V0VHlwZShCYXNlbGluZVZpc3VhbElEUmVnaXN0cnkKCQkJCS5nZXRUeXBlKEJhc2VBY3Rpdml0eUVkaXRQYXJ0LlZJU1VBTF9JRCkpOwoJCVZpZXdVdGlsLmluc2VydENoaWxkVmlldyhjb250YWluZXJWaWV3LCBub2RlLCBpbmRleCwgcGVyc2lzdGVkKTsKCQlub2RlLnNldEVsZW1lbnQoZG9tYWluRWxlbWVudCk7CgkJc3RhbXBTaG9ydGN1dChjb250YWluZXJWaWV3LCBub2RlKTsKCQkvLyBpbml0aWFsaXplRnJvbVByZWZlcmVuY2VzIAoJCWZpbmFsIElQcmVmZXJlbmNlU3RvcmUgcHJlZlN0b3JlID0gKElQcmVmZXJlbmNlU3RvcmUpIHByZWZlcmVuY2VzSGludAoJCQkJLmdldFByZWZlcmVuY2VTdG9yZSgpOwoJCUZvbnRTdHlsZSBub2RlRm9udFN0eWxlID0gKEZvbnRTdHlsZSkgbm9kZQoJCQkJLmdldFN0eWxlKE5vdGF0aW9uUGFja2FnZS5MaXRlcmFscy5GT05UX1NUWUxFKTsKCQlpZiAobm9kZUZvbnRTdHlsZSAhPSBudWxsKSB7CgkJCUZvbnREYXRhIGZvbnREYXRhID0gUHJlZmVyZW5jZUNvbnZlcnRlci5nZXRGb250RGF0YShwcmVmU3RvcmUsCgkJCQkJSVByZWZlcmVuY2VDb25zdGFudHMuUFJFRl9ERUZBVUxUX0ZPTlQpOwoJCQlub2RlRm9udFN0eWxlLnNldEZvbnROYW1lKGZvbnREYXRhLmdldE5hbWUoKSk7CgkJCW5vZGVGb250U3R5bGUuc2V0Rm9udEhlaWdodChmb250RGF0YS5nZXRIZWlnaHQoKSk7CgkJCW5vZGVGb250U3R5bGUuc2V0Qm9sZCgoZm9udERhdGEuZ2V0U3R5bGUoKSAmIFNXVC5CT0xEKSAhPSAwKTsKCQkJbm9kZUZvbnRTdHlsZS5zZXRJdGFsaWMoKGZvbnREYXRhLmdldFN0eWxlKCkgJiBTV1QuSVRBTElDKSAhPSAwKTsKCQkJb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLlJHQiBmb250UkdCID0gUHJlZmVyZW5jZUNvbnZlcnRlcgoJCQkJCS5nZXRDb2xvcihwcmVmU3RvcmUsIElQcmVmZXJlbmNlQ29uc3RhbnRzLlBSRUZfRk9OVF9DT0xPUik7CgkJCW5vZGVGb250U3R5bGUuc2V0Rm9udENvbG9yKEZpZ3VyZVV0aWxpdGllcy5SR0JUb0ludGVnZXIoZm9udFJHQikKCQkJCQkuaW50VmFsdWUoKSk7CgkJfQoJCW9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy5SR0IgZmlsbFJHQiA9IFByZWZlcmVuY2VDb252ZXJ0ZXIuZ2V0Q29sb3IoCgkJCQlwcmVmU3RvcmUsIElQcmVmZXJlbmNlQ29uc3RhbnRzLlBSRUZfRklMTF9DT0xPUik7CgkJVmlld1V0aWwuc2V0U3RydWN0dXJhbEZlYXR1cmVWYWx1ZShub2RlLAoJCQkJTm90YXRpb25QYWNrYWdlLmVJTlNUQU5DRS5nZXRGaWxsU3R5bGVfRmlsbENvbG9yKCksCgkJCQlGaWd1cmVVdGlsaXRpZXMuUkdCVG9JbnRlZ2VyKGZpbGxSR0IpKTsKCQlOb2RlIGxhYmVsNTAwMiA9IGNyZWF0ZUxhYmVsKG5vZGUsCgkJCQlCYXNlbGluZVZpc3VhbElEUmVnaXN0cnkKCQkJCQkJLmdldFR5cGUoQmFzZUFjdGl2aXR5TmFtZUVkaXRQYXJ0LlZJU1VBTF9JRCkpOwoJCWNyZWF0ZUNvbXBhcnRtZW50KAoJCQkJbm9kZSwKCQkJCUJhc2VsaW5lVmlzdWFsSURSZWdpc3RyeQoJCQkJCQkuZ2V0VHlwZShCYXNlQWN0aXZpdHlCYXNlQWN0aXZpdHlTdWJBY3Rpdml0eUNvbXBhcnRtZW50RWRpdFBhcnQuVklTVUFMX0lEKSwKCQkJCXRydWUsIGZhbHNlLCBmYWxzZSwgZmFsc2UpOwoJCXJldHVybiBub2RlOwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwdWJsaWMgTm9kZSBjcmVhdGVCYXNlQXJ0ZWZhY3RfMjAwMihFT2JqZWN0IGRvbWFpbkVsZW1lbnQsCgkJCVZpZXcgY29udGFpbmVyVmlldywgaW50IGluZGV4LCBib29sZWFuIHBlcnNpc3RlZCwKCQkJUHJlZmVyZW5jZXNIaW50IHByZWZlcmVuY2VzSGludCkgewoJCVNoYXBlIG5vZGUgPSBOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZVNoYXBlKCk7CgkJbm9kZS5zZXRMYXlvdXRDb25zdHJhaW50KE5vdGF0aW9uRmFjdG9yeS5lSU5TVEFOQ0UuY3JlYXRlQm91bmRzKCkpOwoJCW5vZGUuc2V0VHlwZShCYXNlbGluZVZpc3VhbElEUmVnaXN0cnkKCQkJCS5nZXRUeXBlKEJhc2VBcnRlZmFjdEVkaXRQYXJ0LlZJU1VBTF9JRCkpOwoJCVZpZXdVdGlsLmluc2VydENoaWxkVmlldyhjb250YWluZXJWaWV3LCBub2RlLCBpbmRleCwgcGVyc2lzdGVkKTsKCQlub2RlLnNldEVsZW1lbnQoZG9tYWluRWxlbWVudCk7CgkJc3RhbXBTaG9ydGN1dChjb250YWluZXJWaWV3LCBub2RlKTsKCQkvLyBpbml0aWFsaXplRnJvbVByZWZlcmVuY2VzIAoJCWZpbmFsIElQcmVmZXJlbmNlU3RvcmUgcHJlZlN0b3JlID0gKElQcmVmZXJlbmNlU3RvcmUpIHByZWZlcmVuY2VzSGludAoJCQkJLmdldFByZWZlcmVuY2VTdG9yZSgpOwoKCQlvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuUkdCIGxpbmVSR0IgPSBQcmVmZXJlbmNlQ29udmVydGVyLmdldENvbG9yKAoJCQkJcHJlZlN0b3JlLCBJUHJlZmVyZW5jZUNvbnN0YW50cy5QUkVGX0xJTkVfQ09MT1IpOwoJCVZpZXdVdGlsLnNldFN0cnVjdHVyYWxGZWF0dXJlVmFsdWUobm9kZSwKCQkJCU5vdGF0aW9uUGFja2FnZS5lSU5TVEFOQ0UuZ2V0TGluZVN0eWxlX0xpbmVDb2xvcigpLAoJCQkJRmlndXJlVXRpbGl0aWVzLlJHQlRvSW50ZWdlcihsaW5lUkdCKSk7CgkJRm9udFN0eWxlIG5vZGVGb250U3R5bGUgPSAoRm9udFN0eWxlKSBub2RlCgkJCQkuZ2V0U3R5bGUoTm90YXRpb25QYWNrYWdlLkxpdGVyYWxzLkZPTlRfU1RZTEUpOwoJCWlmIChub2RlRm9udFN0eWxlICE9IG51bGwpIHsKCQkJRm9udERhdGEgZm9udERhdGEgPSBQcmVmZXJlbmNlQ29udmVydGVyLmdldEZvbnREYXRhKHByZWZTdG9yZSwKCQkJCQlJUHJlZmVyZW5jZUNvbnN0YW50cy5QUkVGX0RFRkFVTFRfRk9OVCk7CgkJCW5vZGVGb250U3R5bGUuc2V0Rm9udE5hbWUoZm9udERhdGEuZ2V0TmFtZSgpKTsKCQkJbm9kZUZvbnRTdHlsZS5zZXRGb250SGVpZ2h0KGZvbnREYXRhLmdldEhlaWdodCgpKTsKCQkJbm9kZUZvbnRTdHlsZS5zZXRCb2xkKChmb250RGF0YS5nZXRTdHlsZSgpICYgU1dULkJPTEQpICE9IDApOwoJCQlub2RlRm9udFN0eWxlLnNldEl0YWxpYygoZm9udERhdGEuZ2V0U3R5bGUoKSAmIFNXVC5JVEFMSUMpICE9IDApOwoJCQlvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuUkdCIGZvbnRSR0IgPSBQcmVmZXJlbmNlQ29udmVydGVyCgkJCQkJLmdldENvbG9yKHByZWZTdG9yZSwgSVByZWZlcmVuY2VDb25zdGFudHMuUFJFRl9GT05UX0NPTE9SKTsKCQkJbm9kZUZvbnRTdHlsZS5zZXRGb250Q29sb3IoRmlndXJlVXRpbGl0aWVzLlJHQlRvSW50ZWdlcihmb250UkdCKQoJCQkJCS5pbnRWYWx1ZSgpKTsKCQl9CgkJb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLlJHQiBmaWxsUkdCID0gUHJlZmVyZW5jZUNvbnZlcnRlci5nZXRDb2xvcigKCQkJCXByZWZTdG9yZSwgSVByZWZlcmVuY2VDb25zdGFudHMuUFJFRl9GSUxMX0NPTE9SKTsKCQlWaWV3VXRpbC5zZXRTdHJ1Y3R1cmFsRmVhdHVyZVZhbHVlKG5vZGUsCgkJCQlOb3RhdGlvblBhY2thZ2UuZUlOU1RBTkNFLmdldEZpbGxTdHlsZV9GaWxsQ29sb3IoKSwKCQkJCUZpZ3VyZVV0aWxpdGllcy5SR0JUb0ludGVnZXIoZmlsbFJHQikpOwoJCU5vZGUgbGFiZWw1MDAzID0gY3JlYXRlTGFiZWwobm9kZSwKCQkJCUJhc2VsaW5lVmlzdWFsSURSZWdpc3RyeQoJCQkJCQkuZ2V0VHlwZShCYXNlQXJ0ZWZhY3ROYW1lRWRpdFBhcnQuVklTVUFMX0lEKSk7CgkJbGFiZWw1MDAzLnNldExheW91dENvbnN0cmFpbnQoTm90YXRpb25GYWN0b3J5LmVJTlNUQU5DRQoJCQkJLmNyZWF0ZUxvY2F0aW9uKCkpOwoJCUxvY2F0aW9uIGxvY2F0aW9uNTAwMyA9IChMb2NhdGlvbikgbGFiZWw1MDAzLmdldExheW91dENvbnN0cmFpbnQoKTsKCQlsb2NhdGlvbjUwMDMuc2V0WCgwKTsKCQlsb2NhdGlvbjUwMDMuc2V0WSg1KTsKCQlyZXR1cm4gbm9kZTsKCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHVibGljIE5vZGUgY3JlYXRlQmFzZVJvbGVfMjAwMyhFT2JqZWN0IGRvbWFpbkVsZW1lbnQsIFZpZXcgY29udGFpbmVyVmlldywKCQkJaW50IGluZGV4LCBib29sZWFuIHBlcnNpc3RlZCwgUHJlZmVyZW5jZXNIaW50IHByZWZlcmVuY2VzSGludCkgewoJCVNoYXBlIG5vZGUgPSBOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZVNoYXBlKCk7CgkJbm9kZS5zZXRMYXlvdXRDb25zdHJhaW50KE5vdGF0aW9uRmFjdG9yeS5lSU5TVEFOQ0UuY3JlYXRlQm91bmRzKCkpOwoJCW5vZGUuc2V0VHlwZShCYXNlbGluZVZpc3VhbElEUmVnaXN0cnkKCQkJCS5nZXRUeXBlKEJhc2VSb2xlRWRpdFBhcnQuVklTVUFMX0lEKSk7CgkJVmlld1V0aWwuaW5zZXJ0Q2hpbGRWaWV3KGNvbnRhaW5lclZpZXcsIG5vZGUsIGluZGV4LCBwZXJzaXN0ZWQpOwoJCW5vZGUuc2V0RWxlbWVudChkb21haW5FbGVtZW50KTsKCQlzdGFtcFNob3J0Y3V0KGNvbnRhaW5lclZpZXcsIG5vZGUpOwoJCS8vIGluaXRpYWxpemVGcm9tUHJlZmVyZW5jZXMgCgkJZmluYWwgSVByZWZlcmVuY2VTdG9yZSBwcmVmU3RvcmUgPSAoSVByZWZlcmVuY2VTdG9yZSkgcHJlZmVyZW5jZXNIaW50CgkJCQkuZ2V0UHJlZmVyZW5jZVN0b3JlKCk7CgoJCW9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy5SR0IgbGluZVJHQiA9IFByZWZlcmVuY2VDb252ZXJ0ZXIuZ2V0Q29sb3IoCgkJCQlwcmVmU3RvcmUsIElQcmVmZXJlbmNlQ29uc3RhbnRzLlBSRUZfTElORV9DT0xPUik7CgkJVmlld1V0aWwuc2V0U3RydWN0dXJhbEZlYXR1cmVWYWx1ZShub2RlLAoJCQkJTm90YXRpb25QYWNrYWdlLmVJTlNUQU5DRS5nZXRMaW5lU3R5bGVfTGluZUNvbG9yKCksCgkJCQlGaWd1cmVVdGlsaXRpZXMuUkdCVG9JbnRlZ2VyKGxpbmVSR0IpKTsKCQlGb250U3R5bGUgbm9kZUZvbnRTdHlsZSA9IChGb250U3R5bGUpIG5vZGUKCQkJCS5nZXRTdHlsZShOb3RhdGlvblBhY2thZ2UuTGl0ZXJhbHMuRk9OVF9TVFlMRSk7CgkJaWYgKG5vZGVGb250U3R5bGUgIT0gbnVsbCkgewoJCQlGb250RGF0YSBmb250RGF0YSA9IFByZWZlcmVuY2VDb252ZXJ0ZXIuZ2V0Rm9udERhdGEocHJlZlN0b3JlLAoJCQkJCUlQcmVmZXJlbmNlQ29uc3RhbnRzLlBSRUZfREVGQVVMVF9GT05UKTsKCQkJbm9kZUZvbnRTdHlsZS5zZXRGb250TmFtZShmb250RGF0YS5nZXROYW1lKCkpOwoJCQlub2RlRm9udFN0eWxlLnNldEZvbnRIZWlnaHQoZm9udERhdGEuZ2V0SGVpZ2h0KCkpOwoJCQlub2RlRm9udFN0eWxlLnNldEJvbGQoKGZvbnREYXRhLmdldFN0eWxlKCkgJiBTV1QuQk9MRCkgIT0gMCk7CgkJCW5vZGVGb250U3R5bGUuc2V0SXRhbGljKChmb250RGF0YS5nZXRTdHlsZSgpICYgU1dULklUQUxJQykgIT0gMCk7CgkJCW9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy5SR0IgZm9udFJHQiA9IFByZWZlcmVuY2VDb252ZXJ0ZXIKCQkJCQkuZ2V0Q29sb3IocHJlZlN0b3JlLCBJUHJlZmVyZW5jZUNvbnN0YW50cy5QUkVGX0ZPTlRfQ09MT1IpOwoJCQlub2RlRm9udFN0eWxlLnNldEZvbnRDb2xvcihGaWd1cmVVdGlsaXRpZXMuUkdCVG9JbnRlZ2VyKGZvbnRSR0IpCgkJCQkJLmludFZhbHVlKCkpOwoJCX0KCQlvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuUkdCIGZpbGxSR0IgPSBQcmVmZXJlbmNlQ29udmVydGVyLmdldENvbG9yKAoJCQkJcHJlZlN0b3JlLCBJUHJlZmVyZW5jZUNvbnN0YW50cy5QUkVGX0ZJTExfQ09MT1IpOwoJCVZpZXdVdGlsLnNldFN0cnVjdHVyYWxGZWF0dXJlVmFsdWUobm9kZSwKCQkJCU5vdGF0aW9uUGFja2FnZS5lSU5TVEFOQ0UuZ2V0RmlsbFN0eWxlX0ZpbGxDb2xvcigpLAoJCQkJRmlndXJlVXRpbGl0aWVzLlJHQlRvSW50ZWdlcihmaWxsUkdCKSk7CgkJTm9kZSBsYWJlbDUwMDQgPSBjcmVhdGVMYWJlbChub2RlLAoJCQkJQmFzZWxpbmVWaXN1YWxJRFJlZ2lzdHJ5CgkJCQkJCS5nZXRUeXBlKEJhc2VSb2xlTmFtZUVkaXRQYXJ0LlZJU1VBTF9JRCkpOwoJCWxhYmVsNTAwNC5zZXRMYXlvdXRDb25zdHJhaW50KE5vdGF0aW9uRmFjdG9yeS5lSU5TVEFOQ0UKCQkJCS5jcmVhdGVMb2NhdGlvbigpKTsKCQlMb2NhdGlvbiBsb2NhdGlvbjUwMDQgPSAoTG9jYXRpb24pIGxhYmVsNTAwNC5nZXRMYXlvdXRDb25zdHJhaW50KCk7CgkJbG9jYXRpb241MDA0LnNldFgoMCk7CgkJbG9jYXRpb241MDA0LnNldFkoNSk7CgkJcmV0dXJuIG5vZGU7Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXB1YmxpYyBOb2RlIGNyZWF0ZUJhc2VBY3Rpdml0eV8zMDAxKEVPYmplY3QgZG9tYWluRWxlbWVudCwKCQkJVmlldyBjb250YWluZXJWaWV3LCBpbnQgaW5kZXgsIGJvb2xlYW4gcGVyc2lzdGVkLAoJCQlQcmVmZXJlbmNlc0hpbnQgcHJlZmVyZW5jZXNIaW50KSB7CgkJTm9kZSBub2RlID0gTm90YXRpb25GYWN0b3J5LmVJTlNUQU5DRS5jcmVhdGVOb2RlKCk7CgkJbm9kZS5nZXRTdHlsZXMoKQoJCQkJLmFkZChOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZURlc2NyaXB0aW9uU3R5bGUoKSk7CgkJbm9kZS5nZXRTdHlsZXMoKS5hZGQoTm90YXRpb25GYWN0b3J5LmVJTlNUQU5DRS5jcmVhdGVGb250U3R5bGUoKSk7CgkJbm9kZS5nZXRTdHlsZXMoKS5hZGQoTm90YXRpb25GYWN0b3J5LmVJTlNUQU5DRS5jcmVhdGVGaWxsU3R5bGUoKSk7CgkJbm9kZS5nZXRTdHlsZXMoKS5hZGQoCgkJCQlOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZUhpbnRlZERpYWdyYW1MaW5rU3R5bGUoKSk7CgkJbm9kZS5zZXRMYXlvdXRDb25zdHJhaW50KE5vdGF0aW9uRmFjdG9yeS5lSU5TVEFOQ0UuY3JlYXRlQm91bmRzKCkpOwoJCW5vZGUuc2V0VHlwZShCYXNlbGluZVZpc3VhbElEUmVnaXN0cnkKCQkJCS5nZXRUeXBlKEJhc2VBY3Rpdml0eTJFZGl0UGFydC5WSVNVQUxfSUQpKTsKCQlWaWV3VXRpbC5pbnNlcnRDaGlsZFZpZXcoY29udGFpbmVyVmlldywgbm9kZSwgaW5kZXgsIHBlcnNpc3RlZCk7CgkJbm9kZS5zZXRFbGVtZW50KGRvbWFpbkVsZW1lbnQpOwoJCS8vIGluaXRpYWxpemVGcm9tUHJlZmVyZW5jZXMgCgkJZmluYWwgSVByZWZlcmVuY2VTdG9yZSBwcmVmU3RvcmUgPSAoSVByZWZlcmVuY2VTdG9yZSkgcHJlZmVyZW5jZXNIaW50CgkJCQkuZ2V0UHJlZmVyZW5jZVN0b3JlKCk7CgkJRm9udFN0eWxlIG5vZGVGb250U3R5bGUgPSAoRm9udFN0eWxlKSBub2RlCgkJCQkuZ2V0U3R5bGUoTm90YXRpb25QYWNrYWdlLkxpdGVyYWxzLkZPTlRfU1RZTEUpOwoJCWlmIChub2RlRm9udFN0eWxlICE9IG51bGwpIHsKCQkJRm9udERhdGEgZm9udERhdGEgPSBQcmVmZXJlbmNlQ29udmVydGVyLmdldEZvbnREYXRhKHByZWZTdG9yZSwKCQkJCQlJUHJlZmVyZW5jZUNvbnN0YW50cy5QUkVGX0RFRkFVTFRfRk9OVCk7CgkJCW5vZGVGb250U3R5bGUuc2V0Rm9udE5hbWUoZm9udERhdGEuZ2V0TmFtZSgpKTsKCQkJbm9kZUZvbnRTdHlsZS5zZXRGb250SGVpZ2h0KGZvbnREYXRhLmdldEhlaWdodCgpKTsKCQkJbm9kZUZvbnRTdHlsZS5zZXRCb2xkKChmb250RGF0YS5nZXRTdHlsZSgpICYgU1dULkJPTEQpICE9IDApOwoJCQlub2RlRm9udFN0eWxlLnNldEl0YWxpYygoZm9udERhdGEuZ2V0U3R5bGUoKSAmIFNXVC5JVEFMSUMpICE9IDApOwoJCQlvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuUkdCIGZvbnRSR0IgPSBQcmVmZXJlbmNlQ29udmVydGVyCgkJCQkJLmdldENvbG9yKHByZWZTdG9yZSwgSVByZWZlcmVuY2VDb25zdGFudHMuUFJFRl9GT05UX0NPTE9SKTsKCQkJbm9kZUZvbnRTdHlsZS5zZXRGb250Q29sb3IoRmlndXJlVXRpbGl0aWVzLlJHQlRvSW50ZWdlcihmb250UkdCKQoJCQkJCS5pbnRWYWx1ZSgpKTsKCQl9CgkJb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLlJHQiBmaWxsUkdCID0gUHJlZmVyZW5jZUNvbnZlcnRlci5nZXRDb2xvcigKCQkJCXByZWZTdG9yZSwgSVByZWZlcmVuY2VDb25zdGFudHMuUFJFRl9GSUxMX0NPTE9SKTsKCQlWaWV3VXRpbC5zZXRTdHJ1Y3R1cmFsRmVhdHVyZVZhbHVlKG5vZGUsCgkJCQlOb3RhdGlvblBhY2thZ2UuZUlOU1RBTkNFLmdldEZpbGxTdHlsZV9GaWxsQ29sb3IoKSwKCQkJCUZpZ3VyZVV0aWxpdGllcy5SR0JUb0ludGVnZXIoZmlsbFJHQikpOwoJCU5vZGUgbGFiZWw1MDAxID0gY3JlYXRlTGFiZWwobm9kZSwKCQkJCUJhc2VsaW5lVmlzdWFsSURSZWdpc3RyeQoJCQkJCQkuZ2V0VHlwZShCYXNlQWN0aXZpdHlOYW1lMkVkaXRQYXJ0LlZJU1VBTF9JRCkpOwoJCWNyZWF0ZUNvbXBhcnRtZW50KAoJCQkJbm9kZSwKCQkJCUJhc2VsaW5lVmlzdWFsSURSZWdpc3RyeQoJCQkJCQkuZ2V0VHlwZShCYXNlQWN0aXZpdHlCYXNlQWN0aXZpdHlTdWJBY3Rpdml0eUNvbXBhcnRtZW50MkVkaXRQYXJ0LlZJU1VBTF9JRCksCgkJCQl0cnVlLCBmYWxzZSwgZmFsc2UsIGZhbHNlKTsKCQlyZXR1cm4gbm9kZTsKCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHVibGljIEVkZ2UgY3JlYXRlQmFzZUFjdGl2aXR5UmVxdWlyZWRBcnRlZmFjdF80MDAxKFZpZXcgY29udGFpbmVyVmlldywKCQkJaW50IGluZGV4LCBib29sZWFuIHBlcnNpc3RlZCwgUHJlZmVyZW5jZXNIaW50IHByZWZlcmVuY2VzSGludCkgewoJCUVkZ2UgZWRnZSA9IE5vdGF0aW9uRmFjdG9yeS5lSU5TVEFOQ0UuY3JlYXRlRWRnZSgpOwoJCWVkZ2UuZ2V0U3R5bGVzKCkuYWRkKE5vdGF0aW9uRmFjdG9yeS5lSU5TVEFOQ0UuY3JlYXRlUm91dGluZ1N0eWxlKCkpOwoJCWVkZ2UuZ2V0U3R5bGVzKCkuYWRkKE5vdGF0aW9uRmFjdG9yeS5lSU5TVEFOQ0UuY3JlYXRlRm9udFN0eWxlKCkpOwoJCVJlbGF0aXZlQmVuZHBvaW50cyBiZW5kcG9pbnRzID0gTm90YXRpb25GYWN0b3J5LmVJTlNUQU5DRQoJCQkJLmNyZWF0ZVJlbGF0aXZlQmVuZHBvaW50cygpOwoJCUFycmF5TGlzdDxSZWxhdGl2ZUJlbmRwb2ludD4gcG9pbnRzID0gbmV3IEFycmF5TGlzdDxSZWxhdGl2ZUJlbmRwb2ludD4oCgkJCQkyKTsKCQlwb2ludHMuYWRkKG5ldyBSZWxhdGl2ZUJlbmRwb2ludCgpKTsKCQlwb2ludHMuYWRkKG5ldyBSZWxhdGl2ZUJlbmRwb2ludCgpKTsKCQliZW5kcG9pbnRzLnNldFBvaW50cyhwb2ludHMpOwoJCWVkZ2Uuc2V0QmVuZHBvaW50cyhiZW5kcG9pbnRzKTsKCQlWaWV3VXRpbC5pbnNlcnRDaGlsZFZpZXcoY29udGFpbmVyVmlldywgZWRnZSwgaW5kZXgsIHBlcnNpc3RlZCk7CgkJZWRnZS5zZXRUeXBlKEJhc2VsaW5lVmlzdWFsSURSZWdpc3RyeQoJCQkJLmdldFR5cGUoQmFzZUFjdGl2aXR5UmVxdWlyZWRBcnRlZmFjdEVkaXRQYXJ0LlZJU1VBTF9JRCkpOwoJCWVkZ2Uuc2V0RWxlbWVudChudWxsKTsKCQkvLyBpbml0aWFsaXplUHJlZmVyZW5jZXMKCQlmaW5hbCBJUHJlZmVyZW5jZVN0b3JlIHByZWZTdG9yZSA9IChJUHJlZmVyZW5jZVN0b3JlKSBwcmVmZXJlbmNlc0hpbnQKCQkJCS5nZXRQcmVmZXJlbmNlU3RvcmUoKTsKCQlGb250U3R5bGUgZWRnZUZvbnRTdHlsZSA9IChGb250U3R5bGUpIGVkZ2UKCQkJCS5nZXRTdHlsZShOb3RhdGlvblBhY2thZ2UuTGl0ZXJhbHMuRk9OVF9TVFlMRSk7CgkJaWYgKGVkZ2VGb250U3R5bGUgIT0gbnVsbCkgewoJCQlGb250RGF0YSBmb250RGF0YSA9IFByZWZlcmVuY2VDb252ZXJ0ZXIuZ2V0Rm9udERhdGEocHJlZlN0b3JlLAoJCQkJCUlQcmVmZXJlbmNlQ29uc3RhbnRzLlBSRUZfREVGQVVMVF9GT05UKTsKCQkJZWRnZUZvbnRTdHlsZS5zZXRGb250TmFtZShmb250RGF0YS5nZXROYW1lKCkpOwoJCQllZGdlRm9udFN0eWxlLnNldEZvbnRIZWlnaHQoZm9udERhdGEuZ2V0SGVpZ2h0KCkpOwoJCQllZGdlRm9udFN0eWxlLnNldEJvbGQoKGZvbnREYXRhLmdldFN0eWxlKCkgJiBTV1QuQk9MRCkgIT0gMCk7CgkJCWVkZ2VGb250U3R5bGUuc2V0SXRhbGljKChmb250RGF0YS5nZXRTdHlsZSgpICYgU1dULklUQUxJQykgIT0gMCk7CgkJCW9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy5SR0IgZm9udFJHQiA9IFByZWZlcmVuY2VDb252ZXJ0ZXIKCQkJCQkuZ2V0Q29sb3IocHJlZlN0b3JlLCBJUHJlZmVyZW5jZUNvbnN0YW50cy5QUkVGX0ZPTlRfQ09MT1IpOwoJCQllZGdlRm9udFN0eWxlLnNldEZvbnRDb2xvcihGaWd1cmVVdGlsaXRpZXMuUkdCVG9JbnRlZ2VyKGZvbnRSR0IpCgkJCQkJLmludFZhbHVlKCkpOwoJCX0KCQlSb3V0aW5nIHJvdXRpbmcgPSBSb3V0aW5nLmdldChwcmVmU3RvcmUKCQkJCS5nZXRJbnQoSVByZWZlcmVuY2VDb25zdGFudHMuUFJFRl9MSU5FX1NUWUxFKSk7CgkJaWYgKHJvdXRpbmcgIT0gbnVsbCkgewoJCQlWaWV3VXRpbC5zZXRTdHJ1Y3R1cmFsRmVhdHVyZVZhbHVlKGVkZ2UsCgkJCQkJTm90YXRpb25QYWNrYWdlLmVJTlNUQU5DRS5nZXRSb3V0aW5nU3R5bGVfUm91dGluZygpLAoJCQkJCXJvdXRpbmcpOwoJCX0KCQlOb2RlIGxhYmVsNjAwMSA9IGNyZWF0ZUxhYmVsKGVkZ2UsCgkJCQlCYXNlbGluZVZpc3VhbElEUmVnaXN0cnkKCQkJCQkJLmdldFR5cGUoV3JhcHBpbmdMYWJlbEVkaXRQYXJ0LlZJU1VBTF9JRCkpOwoJCWxhYmVsNjAwMS5nZXRTdHlsZXMoKS5hZGQoCgkJCQlOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZURlc2NyaXB0aW9uU3R5bGUoKSk7CgkJbGFiZWw2MDAxLnNldExheW91dENvbnN0cmFpbnQoTm90YXRpb25GYWN0b3J5LmVJTlNUQU5DRQoJCQkJLmNyZWF0ZUxvY2F0aW9uKCkpOwoJCUxvY2F0aW9uIGxvY2F0aW9uNjAwMSA9IChMb2NhdGlvbikgbGFiZWw2MDAxLmdldExheW91dENvbnN0cmFpbnQoKTsKCQlsb2NhdGlvbjYwMDEuc2V0WCgwKTsKCQlsb2NhdGlvbjYwMDEuc2V0WSg0MCk7CgkJcmV0dXJuIGVkZ2U7Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXB1YmxpYyBFZGdlIGNyZWF0ZUJhc2VBY3Rpdml0eVByb2R1Y2VkQXJ0ZWZhY3RfNDAwMihWaWV3IGNvbnRhaW5lclZpZXcsCgkJCWludCBpbmRleCwgYm9vbGVhbiBwZXJzaXN0ZWQsIFByZWZlcmVuY2VzSGludCBwcmVmZXJlbmNlc0hpbnQpIHsKCQlFZGdlIGVkZ2UgPSBOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZUVkZ2UoKTsKCQllZGdlLmdldFN0eWxlcygpLmFkZChOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZVJvdXRpbmdTdHlsZSgpKTsKCQllZGdlLmdldFN0eWxlcygpLmFkZChOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZUZvbnRTdHlsZSgpKTsKCQlSZWxhdGl2ZUJlbmRwb2ludHMgYmVuZHBvaW50cyA9IE5vdGF0aW9uRmFjdG9yeS5lSU5TVEFOQ0UKCQkJCS5jcmVhdGVSZWxhdGl2ZUJlbmRwb2ludHMoKTsKCQlBcnJheUxpc3Q8UmVsYXRpdmVCZW5kcG9pbnQ+IHBvaW50cyA9IG5ldyBBcnJheUxpc3Q8UmVsYXRpdmVCZW5kcG9pbnQ+KAoJCQkJMik7CgkJcG9pbnRzLmFkZChuZXcgUmVsYXRpdmVCZW5kcG9pbnQoKSk7CgkJcG9pbnRzLmFkZChuZXcgUmVsYXRpdmVCZW5kcG9pbnQoKSk7CgkJYmVuZHBvaW50cy5zZXRQb2ludHMocG9pbnRzKTsKCQllZGdlLnNldEJlbmRwb2ludHMoYmVuZHBvaW50cyk7CgkJVmlld1V0aWwuaW5zZXJ0Q2hpbGRWaWV3KGNvbnRhaW5lclZpZXcsIGVkZ2UsIGluZGV4LCBwZXJzaXN0ZWQpOwoJCWVkZ2Uuc2V0VHlwZShCYXNlbGluZVZpc3VhbElEUmVnaXN0cnkKCQkJCS5nZXRUeXBlKEJhc2VBY3Rpdml0eVByb2R1Y2VkQXJ0ZWZhY3RFZGl0UGFydC5WSVNVQUxfSUQpKTsKCQllZGdlLnNldEVsZW1lbnQobnVsbCk7CgkJLy8gaW5pdGlhbGl6ZVByZWZlcmVuY2VzCgkJZmluYWwgSVByZWZlcmVuY2VTdG9yZSBwcmVmU3RvcmUgPSAoSVByZWZlcmVuY2VTdG9yZSkgcHJlZmVyZW5jZXNIaW50CgkJCQkuZ2V0UHJlZmVyZW5jZVN0b3JlKCk7CgkJRm9udFN0eWxlIGVkZ2VGb250U3R5bGUgPSAoRm9udFN0eWxlKSBlZGdlCgkJCQkuZ2V0U3R5bGUoTm90YXRpb25QYWNrYWdlLkxpdGVyYWxzLkZPTlRfU1RZTEUpOwoJCWlmIChlZGdlRm9udFN0eWxlICE9IG51bGwpIHsKCQkJRm9udERhdGEgZm9udERhdGEgPSBQcmVmZXJlbmNlQ29udmVydGVyLmdldEZvbnREYXRhKHByZWZTdG9yZSwKCQkJCQlJUHJlZmVyZW5jZUNvbnN0YW50cy5QUkVGX0RFRkFVTFRfRk9OVCk7CgkJCWVkZ2VGb250U3R5bGUuc2V0Rm9udE5hbWUoZm9udERhdGEuZ2V0TmFtZSgpKTsKCQkJZWRnZUZvbnRTdHlsZS5zZXRGb250SGVpZ2h0KGZvbnREYXRhLmdldEhlaWdodCgpKTsKCQkJZWRnZUZvbnRTdHlsZS5zZXRCb2xkKChmb250RGF0YS5nZXRTdHlsZSgpICYgU1dULkJPTEQpICE9IDApOwoJCQllZGdlRm9udFN0eWxlLnNldEl0YWxpYygoZm9udERhdGEuZ2V0U3R5bGUoKSAmIFNXVC5JVEFMSUMpICE9IDApOwoJCQlvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuUkdCIGZvbnRSR0IgPSBQcmVmZXJlbmNlQ29udmVydGVyCgkJCQkJLmdldENvbG9yKHByZWZTdG9yZSwgSVByZWZlcmVuY2VDb25zdGFudHMuUFJFRl9GT05UX0NPTE9SKTsKCQkJZWRnZUZvbnRTdHlsZS5zZXRGb250Q29sb3IoRmlndXJlVXRpbGl0aWVzLlJHQlRvSW50ZWdlcihmb250UkdCKQoJCQkJCS5pbnRWYWx1ZSgpKTsKCQl9CgkJUm91dGluZyByb3V0aW5nID0gUm91dGluZy5nZXQocHJlZlN0b3JlCgkJCQkuZ2V0SW50KElQcmVmZXJlbmNlQ29uc3RhbnRzLlBSRUZfTElORV9TVFlMRSkpOwoJCWlmIChyb3V0aW5nICE9IG51bGwpIHsKCQkJVmlld1V0aWwuc2V0U3RydWN0dXJhbEZlYXR1cmVWYWx1ZShlZGdlLAoJCQkJCU5vdGF0aW9uUGFja2FnZS5lSU5TVEFOQ0UuZ2V0Um91dGluZ1N0eWxlX1JvdXRpbmcoKSwKCQkJCQlyb3V0aW5nKTsKCQl9CgkJTm9kZSBsYWJlbDYwMDIgPSBjcmVhdGVMYWJlbChlZGdlLAoJCQkJQmFzZWxpbmVWaXN1YWxJRFJlZ2lzdHJ5CgkJCQkJCS5nZXRUeXBlKFdyYXBwaW5nTGFiZWwyRWRpdFBhcnQuVklTVUFMX0lEKSk7CgkJbGFiZWw2MDAyLmdldFN0eWxlcygpLmFkZCgKCQkJCU5vdGF0aW9uRmFjdG9yeS5lSU5TVEFOQ0UuY3JlYXRlRGVzY3JpcHRpb25TdHlsZSgpKTsKCQlsYWJlbDYwMDIuc2V0TGF5b3V0Q29uc3RyYWludChOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFCgkJCQkuY3JlYXRlTG9jYXRpb24oKSk7CgkJTG9jYXRpb24gbG9jYXRpb242MDAyID0gKExvY2F0aW9uKSBsYWJlbDYwMDIuZ2V0TGF5b3V0Q29uc3RyYWludCgpOwoJCWxvY2F0aW9uNjAwMi5zZXRYKDApOwoJCWxvY2F0aW9uNjAwMi5zZXRZKDQwKTsKCQlyZXR1cm4gZWRnZTsKCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHVibGljIEVkZ2UgY3JlYXRlQmFzZUFjdGl2aXR5UHJlY2VkaW5nQWN0aXZpdHlfNDAwMyhWaWV3IGNvbnRhaW5lclZpZXcsCgkJCWludCBpbmRleCwgYm9vbGVhbiBwZXJzaXN0ZWQsIFByZWZlcmVuY2VzSGludCBwcmVmZXJlbmNlc0hpbnQpIHsKCQlDb25uZWN0b3IgZWRnZSA9IE5vdGF0aW9uRmFjdG9yeS5lSU5TVEFOQ0UuY3JlYXRlQ29ubmVjdG9yKCk7CgkJZWRnZS5nZXRTdHlsZXMoKS5hZGQoTm90YXRpb25GYWN0b3J5LmVJTlNUQU5DRS5jcmVhdGVGb250U3R5bGUoKSk7CgkJUmVsYXRpdmVCZW5kcG9pbnRzIGJlbmRwb2ludHMgPSBOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFCgkJCQkuY3JlYXRlUmVsYXRpdmVCZW5kcG9pbnRzKCk7CgkJQXJyYXlMaXN0PFJlbGF0aXZlQmVuZHBvaW50PiBwb2ludHMgPSBuZXcgQXJyYXlMaXN0PFJlbGF0aXZlQmVuZHBvaW50PigKCQkJCTIpOwoJCXBvaW50cy5hZGQobmV3IFJlbGF0aXZlQmVuZHBvaW50KCkpOwoJCXBvaW50cy5hZGQobmV3IFJlbGF0aXZlQmVuZHBvaW50KCkpOwoJCWJlbmRwb2ludHMuc2V0UG9pbnRzKHBvaW50cyk7CgkJZWRnZS5zZXRCZW5kcG9pbnRzKGJlbmRwb2ludHMpOwoJCVZpZXdVdGlsLmluc2VydENoaWxkVmlldyhjb250YWluZXJWaWV3LCBlZGdlLCBpbmRleCwgcGVyc2lzdGVkKTsKCQllZGdlLnNldFR5cGUoQmFzZWxpbmVWaXN1YWxJRFJlZ2lzdHJ5CgkJCQkuZ2V0VHlwZShCYXNlQWN0aXZpdHlQcmVjZWRpbmdBY3Rpdml0eUVkaXRQYXJ0LlZJU1VBTF9JRCkpOwoJCWVkZ2Uuc2V0RWxlbWVudChudWxsKTsKCQkvLyBpbml0aWFsaXplUHJlZmVyZW5jZXMKCQlmaW5hbCBJUHJlZmVyZW5jZVN0b3JlIHByZWZTdG9yZSA9IChJUHJlZmVyZW5jZVN0b3JlKSBwcmVmZXJlbmNlc0hpbnQKCQkJCS5nZXRQcmVmZXJlbmNlU3RvcmUoKTsKCgkJb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLlJHQiBsaW5lUkdCID0gUHJlZmVyZW5jZUNvbnZlcnRlci5nZXRDb2xvcigKCQkJCXByZWZTdG9yZSwgSVByZWZlcmVuY2VDb25zdGFudHMuUFJFRl9MSU5FX0NPTE9SKTsKCQlWaWV3VXRpbC5zZXRTdHJ1Y3R1cmFsRmVhdHVyZVZhbHVlKGVkZ2UsCgkJCQlOb3RhdGlvblBhY2thZ2UuZUlOU1RBTkNFLmdldExpbmVTdHlsZV9MaW5lQ29sb3IoKSwKCQkJCUZpZ3VyZVV0aWxpdGllcy5SR0JUb0ludGVnZXIobGluZVJHQikpOwoJCUZvbnRTdHlsZSBlZGdlRm9udFN0eWxlID0gKEZvbnRTdHlsZSkgZWRnZQoJCQkJLmdldFN0eWxlKE5vdGF0aW9uUGFja2FnZS5MaXRlcmFscy5GT05UX1NUWUxFKTsKCQlpZiAoZWRnZUZvbnRTdHlsZSAhPSBudWxsKSB7CgkJCUZvbnREYXRhIGZvbnREYXRhID0gUHJlZmVyZW5jZUNvbnZlcnRlci5nZXRGb250RGF0YShwcmVmU3RvcmUsCgkJCQkJSVByZWZlcmVuY2VDb25zdGFudHMuUFJFRl9ERUZBVUxUX0ZPTlQpOwoJCQllZGdlRm9udFN0eWxlLnNldEZvbnROYW1lKGZvbnREYXRhLmdldE5hbWUoKSk7CgkJCWVkZ2VGb250U3R5bGUuc2V0Rm9udEhlaWdodChmb250RGF0YS5nZXRIZWlnaHQoKSk7CgkJCWVkZ2VGb250U3R5bGUuc2V0Qm9sZCgoZm9udERhdGEuZ2V0U3R5bGUoKSAmIFNXVC5CT0xEKSAhPSAwKTsKCQkJZWRnZUZvbnRTdHlsZS5zZXRJdGFsaWMoKGZvbnREYXRhLmdldFN0eWxlKCkgJiBTV1QuSVRBTElDKSAhPSAwKTsKCQkJb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLlJHQiBmb250UkdCID0gUHJlZmVyZW5jZUNvbnZlcnRlcgoJCQkJCS5nZXRDb2xvcihwcmVmU3RvcmUsIElQcmVmZXJlbmNlQ29uc3RhbnRzLlBSRUZfRk9OVF9DT0xPUik7CgkJCWVkZ2VGb250U3R5bGUuc2V0Rm9udENvbG9yKEZpZ3VyZVV0aWxpdGllcy5SR0JUb0ludGVnZXIoZm9udFJHQikKCQkJCQkuaW50VmFsdWUoKSk7CgkJfQoJCVJvdXRpbmcgcm91dGluZyA9IFJvdXRpbmcuZ2V0KHByZWZTdG9yZQoJCQkJLmdldEludChJUHJlZmVyZW5jZUNvbnN0YW50cy5QUkVGX0xJTkVfU1RZTEUpKTsKCQlpZiAocm91dGluZyAhPSBudWxsKSB7CgkJCVZpZXdVdGlsLnNldFN0cnVjdHVyYWxGZWF0dXJlVmFsdWUoZWRnZSwKCQkJCQlOb3RhdGlvblBhY2thZ2UuZUlOU1RBTkNFLmdldFJvdXRpbmdTdHlsZV9Sb3V0aW5nKCksCgkJCQkJcm91dGluZyk7CgkJfQoJCU5vZGUgbGFiZWw2MDAzID0gY3JlYXRlTGFiZWwoZWRnZSwKCQkJCUJhc2VsaW5lVmlzdWFsSURSZWdpc3RyeQoJCQkJCQkuZ2V0VHlwZShXcmFwcGluZ0xhYmVsM0VkaXRQYXJ0LlZJU1VBTF9JRCkpOwoJCWxhYmVsNjAwMy5nZXRTdHlsZXMoKS5hZGQoCgkJCQlOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZURlc2NyaXB0aW9uU3R5bGUoKSk7CgkJbGFiZWw2MDAzLnNldExheW91dENvbnN0cmFpbnQoTm90YXRpb25GYWN0b3J5LmVJTlNUQU5DRQoJCQkJLmNyZWF0ZUxvY2F0aW9uKCkpOwoJCUxvY2F0aW9uIGxvY2F0aW9uNjAwMyA9IChMb2NhdGlvbikgbGFiZWw2MDAzLmdldExheW91dENvbnN0cmFpbnQoKTsKCQlsb2NhdGlvbjYwMDMuc2V0WCgwKTsKCQlsb2NhdGlvbjYwMDMuc2V0WSg0MCk7CgkJcmV0dXJuIGVkZ2U7Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXB1YmxpYyBFZGdlIGNyZWF0ZUJhc2VBY3Rpdml0eVJvbGVfNDAwNChWaWV3IGNvbnRhaW5lclZpZXcsIGludCBpbmRleCwKCQkJYm9vbGVhbiBwZXJzaXN0ZWQsIFByZWZlcmVuY2VzSGludCBwcmVmZXJlbmNlc0hpbnQpIHsKCQlFZGdlIGVkZ2UgPSBOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZUVkZ2UoKTsKCQllZGdlLmdldFN0eWxlcygpLmFkZChOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZVJvdXRpbmdTdHlsZSgpKTsKCQllZGdlLmdldFN0eWxlcygpLmFkZChOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZUZvbnRTdHlsZSgpKTsKCQlSZWxhdGl2ZUJlbmRwb2ludHMgYmVuZHBvaW50cyA9IE5vdGF0aW9uRmFjdG9yeS5lSU5TVEFOQ0UKCQkJCS5jcmVhdGVSZWxhdGl2ZUJlbmRwb2ludHMoKTsKCQlBcnJheUxpc3Q8UmVsYXRpdmVCZW5kcG9pbnQ+IHBvaW50cyA9IG5ldyBBcnJheUxpc3Q8UmVsYXRpdmVCZW5kcG9pbnQ+KAoJCQkJMik7CgkJcG9pbnRzLmFkZChuZXcgUmVsYXRpdmVCZW5kcG9pbnQoKSk7CgkJcG9pbnRzLmFkZChuZXcgUmVsYXRpdmVCZW5kcG9pbnQoKSk7CgkJYmVuZHBvaW50cy5zZXRQb2ludHMocG9pbnRzKTsKCQllZGdlLnNldEJlbmRwb2ludHMoYmVuZHBvaW50cyk7CgkJVmlld1V0aWwuaW5zZXJ0Q2hpbGRWaWV3KGNvbnRhaW5lclZpZXcsIGVkZ2UsIGluZGV4LCBwZXJzaXN0ZWQpOwoJCWVkZ2Uuc2V0VHlwZShCYXNlbGluZVZpc3VhbElEUmVnaXN0cnkKCQkJCS5nZXRUeXBlKEJhc2VBY3Rpdml0eVJvbGVFZGl0UGFydC5WSVNVQUxfSUQpKTsKCQllZGdlLnNldEVsZW1lbnQobnVsbCk7CgkJLy8gaW5pdGlhbGl6ZVByZWZlcmVuY2VzCgkJZmluYWwgSVByZWZlcmVuY2VTdG9yZSBwcmVmU3RvcmUgPSAoSVByZWZlcmVuY2VTdG9yZSkgcHJlZmVyZW5jZXNIaW50CgkJCQkuZ2V0UHJlZmVyZW5jZVN0b3JlKCk7CgkJRm9udFN0eWxlIGVkZ2VGb250U3R5bGUgPSAoRm9udFN0eWxlKSBlZGdlCgkJCQkuZ2V0U3R5bGUoTm90YXRpb25QYWNrYWdlLkxpdGVyYWxzLkZPTlRfU1RZTEUpOwoJCWlmIChlZGdlRm9udFN0eWxlICE9IG51bGwpIHsKCQkJRm9udERhdGEgZm9udERhdGEgPSBQcmVmZXJlbmNlQ29udmVydGVyLmdldEZvbnREYXRhKHByZWZTdG9yZSwKCQkJCQlJUHJlZmVyZW5jZUNvbnN0YW50cy5QUkVGX0RFRkFVTFRfRk9OVCk7CgkJCWVkZ2VGb250U3R5bGUuc2V0Rm9udE5hbWUoZm9udERhdGEuZ2V0TmFtZSgpKTsKCQkJZWRnZUZvbnRTdHlsZS5zZXRGb250SGVpZ2h0KGZvbnREYXRhLmdldEhlaWdodCgpKTsKCQkJZWRnZUZvbnRTdHlsZS5zZXRCb2xkKChmb250RGF0YS5nZXRTdHlsZSgpICYgU1dULkJPTEQpICE9IDApOwoJCQllZGdlRm9udFN0eWxlLnNldEl0YWxpYygoZm9udERhdGEuZ2V0U3R5bGUoKSAmIFNXVC5JVEFMSUMpICE9IDApOwoJCQlvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuUkdCIGZvbnRSR0IgPSBQcmVmZXJlbmNlQ29udmVydGVyCgkJCQkJLmdldENvbG9yKHByZWZTdG9yZSwgSVByZWZlcmVuY2VDb25zdGFudHMuUFJFRl9GT05UX0NPTE9SKTsKCQkJZWRnZUZvbnRTdHlsZS5zZXRGb250Q29sb3IoRmlndXJlVXRpbGl0aWVzLlJHQlRvSW50ZWdlcihmb250UkdCKQoJCQkJCS5pbnRWYWx1ZSgpKTsKCQl9CgkJUm91dGluZyByb3V0aW5nID0gUm91dGluZy5nZXQocHJlZlN0b3JlCgkJCQkuZ2V0SW50KElQcmVmZXJlbmNlQ29uc3RhbnRzLlBSRUZfTElORV9TVFlMRSkpOwoJCWlmIChyb3V0aW5nICE9IG51bGwpIHsKCQkJVmlld1V0aWwuc2V0U3RydWN0dXJhbEZlYXR1cmVWYWx1ZShlZGdlLAoJCQkJCU5vdGF0aW9uUGFja2FnZS5lSU5TVEFOQ0UuZ2V0Um91dGluZ1N0eWxlX1JvdXRpbmcoKSwKCQkJCQlyb3V0aW5nKTsKCQl9CgkJTm9kZSBsYWJlbDYwMDQgPSBjcmVhdGVMYWJlbChlZGdlLAoJCQkJQmFzZWxpbmVWaXN1YWxJRFJlZ2lzdHJ5CgkJCQkJCS5nZXRUeXBlKEJhc2VSb2xlTGFiZWxFZGl0UGFydC5WSVNVQUxfSUQpKTsKCQlsYWJlbDYwMDQuZ2V0U3R5bGVzKCkuYWRkKAoJCQkJTm90YXRpb25GYWN0b3J5LmVJTlNUQU5DRS5jcmVhdGVEZXNjcmlwdGlvblN0eWxlKCkpOwoJCWxhYmVsNjAwNC5zZXRMYXlvdXRDb25zdHJhaW50KE5vdGF0aW9uRmFjdG9yeS5lSU5TVEFOQ0UKCQkJCS5jcmVhdGVMb2NhdGlvbigpKTsKCQlMb2NhdGlvbiBsb2NhdGlvbjYwMDQgPSAoTG9jYXRpb24pIGxhYmVsNjAwNC5nZXRMYXlvdXRDb25zdHJhaW50KCk7CgkJbG9jYXRpb242MDA0LnNldFgoMCk7CgkJbG9jYXRpb242MDA0LnNldFkoNDApOwoJCXJldHVybiBlZGdlOwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwcml2YXRlIHZvaWQgc3RhbXBTaG9ydGN1dChWaWV3IGNvbnRhaW5lclZpZXcsIE5vZGUgdGFyZ2V0KSB7CgkJaWYgKCFCYXNlRnJhbWV3b3JrRWRpdFBhcnQuTU9ERUxfSUQuZXF1YWxzKEJhc2VsaW5lVmlzdWFsSURSZWdpc3RyeQoJCQkJLmdldE1vZGVsSUQoY29udGFpbmVyVmlldykpKSB7CgkJCUVBbm5vdGF0aW9uIHNob3J0Y3V0QW5ub3RhdGlvbiA9IEVjb3JlRmFjdG9yeS5lSU5TVEFOQ0UKCQkJCQkuY3JlYXRlRUFubm90YXRpb24oKTsKCQkJc2hvcnRjdXRBbm5vdGF0aW9uLnNldFNvdXJjZSgiU2hvcnRjdXQiKTsgLy8kTk9OLU5MUy0xJAoJCQlzaG9ydGN1dEFubm90YXRpb24uZ2V0RGV0YWlscygpLnB1dCgKCQkJCQkibW9kZWxJRCIsIEJhc2VGcmFtZXdvcmtFZGl0UGFydC5NT0RFTF9JRCk7IC8vJE5PTi1OTFMtMSQKCQkJdGFyZ2V0LmdldEVBbm5vdGF0aW9ucygpLmFkZChzaG9ydGN1dEFubm90YXRpb24pOwoJCX0KCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJpdmF0ZSBOb2RlIGNyZWF0ZUxhYmVsKFZpZXcgb3duZXIsIFN0cmluZyBoaW50KSB7CgkJRGVjb3JhdGlvbk5vZGUgcnYgPSBOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZURlY29yYXRpb25Ob2RlKCk7CgkJcnYuc2V0VHlwZShoaW50KTsKCQlWaWV3VXRpbC5pbnNlcnRDaGlsZFZpZXcob3duZXIsIHJ2LCBWaWV3VXRpbC5BUFBFTkQsIHRydWUpOwoJCXJldHVybiBydjsKCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJpdmF0ZSBOb2RlIGNyZWF0ZUNvbXBhcnRtZW50KFZpZXcgb3duZXIsIFN0cmluZyBoaW50LAoJCQlib29sZWFuIGNhbkNvbGxhcHNlLCBib29sZWFuIGhhc1RpdGxlLCBib29sZWFuIGNhblNvcnQsCgkJCWJvb2xlYW4gY2FuRmlsdGVyKSB7CgkJLy9TZW1hbnRpY0xpc3RDb21wYXJ0bWVudCBydiA9IE5vdGF0aW9uRmFjdG9yeS5lSU5TVEFOQ0UuY3JlYXRlU2VtYW50aWNMaXN0Q29tcGFydG1lbnQoKTsKCQkvL3J2LnNldFNob3dUaXRsZShzaG93VGl0bGUpOwoJCS8vcnYuc2V0Q29sbGFwc2VkKGlzQ29sbGFwc2VkKTsKCQlOb2RlIHJ2OwoJCWlmIChjYW5Db2xsYXBzZSkgewoJCQlydiA9IE5vdGF0aW9uRmFjdG9yeS5lSU5TVEFOQ0UuY3JlYXRlQmFzaWNDb21wYXJ0bWVudCgpOwoJCX0gZWxzZSB7CgkJCXJ2ID0gTm90YXRpb25GYWN0b3J5LmVJTlNUQU5DRS5jcmVhdGVEZWNvcmF0aW9uTm9kZSgpOwoJCX0KCQlpZiAoaGFzVGl0bGUpIHsKCQkJVGl0bGVTdHlsZSB0cyA9IE5vdGF0aW9uRmFjdG9yeS5lSU5TVEFOQ0UuY3JlYXRlVGl0bGVTdHlsZSgpOwoJCQl0cy5zZXRTaG93VGl0bGUodHJ1ZSk7CgkJCXJ2LmdldFN0eWxlcygpLmFkZCh0cyk7CgkJfQoJCWlmIChjYW5Tb3J0KSB7CgkJCXJ2LmdldFN0eWxlcygpLmFkZChOb3RhdGlvbkZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZVNvcnRpbmdTdHlsZSgpKTsKCQl9CgkJaWYgKGNhbkZpbHRlcikgewoJCQlydi5nZXRTdHlsZXMoKQoJCQkJCS5hZGQoTm90YXRpb25GYWN0b3J5LmVJTlNUQU5DRS5jcmVhdGVGaWx0ZXJpbmdTdHlsZSgpKTsKCQl9CgkJcnYuc2V0VHlwZShoaW50KTsKCQlWaWV3VXRpbC5pbnNlcnRDaGlsZFZpZXcob3duZXIsIHJ2LCBWaWV3VXRpbC5BUFBFTkQsIHRydWUpOwoJCXJldHVybiBydjsKCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJpdmF0ZSBFT2JqZWN0IGdldFNlbWFudGljRWxlbWVudChJQWRhcHRhYmxlIHNlbWFudGljQWRhcHRlcikgewoJCWlmIChzZW1hbnRpY0FkYXB0ZXIgPT0gbnVsbCkgewoJCQlyZXR1cm4gbnVsbDsKCQl9CgkJRU9iamVjdCBlT2JqZWN0ID0gKEVPYmplY3QpIHNlbWFudGljQWRhcHRlci5nZXRBZGFwdGVyKEVPYmplY3QuY2xhc3MpOwoJCWlmIChlT2JqZWN0ICE9IG51bGwpIHsKCQkJcmV0dXJuIEVNRkNvcmVVdGlsLnJlc29sdmUoCgkJCQkJVHJhbnNhY3Rpb25VdGlsLmdldEVkaXRpbmdEb21haW4oZU9iamVjdCksIGVPYmplY3QpOwoJCX0KCQlyZXR1cm4gbnVsbDsKCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJpdmF0ZSBJRWxlbWVudFR5cGUgZ2V0U2VtYW50aWNFbGVtZW50VHlwZShJQWRhcHRhYmxlIHNlbWFudGljQWRhcHRlcikgewoJCWlmIChzZW1hbnRpY0FkYXB0ZXIgPT0gbnVsbCkgewoJCQlyZXR1cm4gbnVsbDsKCQl9CgkJcmV0dXJuIChJRWxlbWVudFR5cGUpIHNlbWFudGljQWRhcHRlci5nZXRBZGFwdGVyKElFbGVtZW50VHlwZS5jbGFzcyk7Cgl9Cn0K