LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDEwIElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKgogKiBDb250cmlidXRvcnM6CiAqICAgICBJQk0gQ29ycG9yYXRpb24gLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnBhY2thZ2Ugb3JnLmVjbGlwc2UuZ2VmOwoKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CgppbXBvcnQgb3JnLmVjbGlwc2UuZHJhdzJkLklGaWd1cmU7CmltcG9ydCBvcmcuZWNsaXBzZS5kcmF3MmQuZ2VvbWV0cnkuUHJlY2lzaW9uUmVjdGFuZ2xlOwppbXBvcnQgb3JnLmVjbGlwc2UuZHJhdzJkLmdlb21ldHJ5LlJlY3RhbmdsZTsKCmltcG9ydCBvcmcuZWNsaXBzZS5nZWYuaGFuZGxlcy5IYW5kbGVCb3VuZHM7CmltcG9ydCBvcmcuZWNsaXBzZS5nZWYucmVxdWVzdHMuR3JvdXBSZXF1ZXN0OwoKLyoqCiAqIEEgdGVtcG9yYXJ5IGhlbHBlciB1c2VkIHRvIHBlcmZvcm0gc25hcHBpbmcgdG8gZXhpc3RpbmcgZWxlbWVudHMuIFRoaXMgaGVscGVyCiAqIGNhbiBiZSB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggdGhlCiAqIHtAbGluayBvcmcuZWNsaXBzZS5nZWYudG9vbHMuRHJhZ0VkaXRQYXJ0c1RyYWNrZXIgRHJhZ0VkaXRQYXJ0c1RyYWNrZXJ9IHdoZW4KICogZHJhZ2dpbmcgZWRpdHBhcnRzIHdpdGhpbiBhIGdyYXBoaWNhbCB2aWV3ZXIuIFNuYXBwaW5nIGlzIGJhc2VkIG9uIHRoZQogKiBleGlzdGluZyBjaGlsZHJlbiBvZiBhIDxJPmNvbnRhaW5lcjwvST4uIFdoZW4gc25hcHBpbmcgYSByZWN0YW5nbGUsIHRoZSBlZGdlcwogKiBvZiB0aGUgcmVjdGFuZ2xlIHdpbGwgc25hcCB0byBlZGdlcyBvZiBvdGhlciByZWN0YW5nbGVzIGdlbmVyYXRlZCBmcm9tIHRoZQogKiBjaGlsZHJlbiBvZiB0aGUgZ2l2ZW4gY29udGFpbmVyLiBTaW1pbGFybHksIHRoZSBjZW50ZXJzIGFuZCBtaWRkbGVzIG9mCiAqIHJlY3RhbmdsZXMgd2lsbCBzbmFwIHRvIGVhY2ggb3RoZXIuCiAqIDxQPgogKiBJZiB0aGUgc25hcCByZXF1ZXN0IGlzIGJlaW5nIG1hZGUgZHVyaW5nIGEgTW92ZSwgUmVwYXJlbnQgb3IgUmVzaXplLCB0aGVuIHRoZQogKiBmaWd1cmVzIG9mIHRoZSBwYXJ0aWNpcGFudHMgb2YgdGhhdCByZXF1ZXN0IHdpbGwgbm90IGJlIHVzZWQgZm9yIHNuYXBwaW5nLiBJZgogKiB0aGUgcmVxdWVzdCBpcyBhIENsb25lLCB0aGVuIHRoZSBmaWd1cmVzIGZvciB0aGUgcGFydHMgYmVpbmcgY2xvbmVkIHdpbGwgYmUKICogdXNlZCBhcyBwb3NzaWJsZSBzbmFwIGxvY2F0aW9ucy4KICogPFA+CiAqIFRoaXMgaGVscGVyIGRvZXMgbm90IGtlZXAgdXAgd2l0aCBjaGFuZ2VzIG1hZGUgdG8gdGhlIGNvbnRhaW5lciBlZGl0cGFydC4KICogQ2xpZW50cyBzaG91bGQgaW5zdGFudGlhdGUgYSBuZXcgaGVscGVyIGVhY2ggdGltZSBvbmUgaXMgcmVxdWVzdGVkIGFuZCBub3QKICogaG9sZCBvbiB0byBpbnN0YW5jZXMgb2YgdGhlIGhlbHBlci4KICogCiAqIEBzaW5jZSAzLjAKICogQGF1dGhvciBSYW5keSBIdWRzb24KICogQGF1dGhvciBQcmF0aWsgU2hhaAogKi8KcHVibGljIGNsYXNzIFNuYXBUb0dlb21ldHJ5IGV4dGVuZHMgU25hcFRvSGVscGVyIHsKCgkvKioKCSAqIEEgcHJvcGVydHkgaW5kaWNhdGluZyB3aGV0aGVyIHRoaXMgaGVscGVyIHNob3VsZCBiZSB1c2VkLiBUaGUgdmFsdWUKCSAqIHNob3VsZCBiZSBhbiBpbnN0YW5jZSBvZiBCb29sZWFuLiBDdXJyZW50bHksIHRoaXMgY2xhc3MgZG9lcyBub3QgY2hlY2sgdG8KCSAqIHNlZSBpZiB0aGUgdmlld2VyIHByb3BlcnR5IGlzIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPi4KCSAqIAoJICogQHNlZSBFZGl0UGFydFZpZXdlciNzZXRQcm9wZXJ0eShTdHJpbmcsIE9iamVjdCkKCSAqLwoJcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJPUEVSVFlfU05BUF9FTkFCTEVEID0gIlNuYXBUb0dlb21ldHJ5LmlzRW5hYmxlZCI7IC8vJE5PTi1OTFMtMSQKCgkvKioKCSAqIFRoZSBrZXkgdXNlZCB0byBpZGVudGlmeSB0aGUgTm9ydGggYW5jaG9yIHBvaW50IGluIHRoZSBleHRlbmRlZCBkYXRhIG9mIGEKCSAqIHJlcXVlc3QuIFRoZSBub3J0aCBhbmNob3IgbWF5IGJlIHNldCB0byBhbiB7QGxpbmsgSW50ZWdlcn0gdmFsdWUKCSAqIGluZGljYXRpbmcgd2hlcmUgdGhlIHNuYXBwaW5nIGlzIG9jY3VycmluZy4gVGhpcyBpcyB1c2VkIGZvciBmZWVkYmFjawoJICogcHVycG9zZXMuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEtFWV9OT1JUSF9BTkNIT1IgPSAiU25hcFRvR2VvbWV0cnkuTm9ydGhBbmNob3IiOyAvLyROT04tTkxTLTEkCgoJLyoqCgkgKiBUaGUga2V5IHVzZWQgdG8gaWRlbnRpZnkgdGhlIFNvdXRoIGFuY2hvciBwb2ludCBpbiB0aGUgZXh0ZW5kZWQgZGF0YSBvZiBhCgkgKiByZXF1ZXN0LiBUaGUgc291dGggYW5jaG9yIG1heSBiZSBzZXQgdG8gYW4ge0BsaW5rIEludGVnZXJ9IHZhbHVlCgkgKiBpbmRpY2F0aW5nIHdoZXJlIHRoZSBzbmFwcGluZyBpcyBvY2N1cnJpbmcuIFRoaXMgaXMgdXNlZCBmb3IgZmVlZGJhY2sKCSAqIHB1cnBvc2VzLgoJICovCglwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBLRVlfU09VVEhfQU5DSE9SID0gIlNuYXBUb0dlb21ldHJ5LlNvdXRoQW5jaG9yIjsgLy8kTk9OLU5MUy0xJAoKCS8qKgoJICogVGhlIGtleSB1c2VkIHRvIGlkZW50aWZ5IHRoZSBXZXN0IGFuY2hvciBwb2ludCBpbiB0aGUgZXh0ZW5kZWQgZGF0YSBvZiBhCgkgKiByZXF1ZXN0LiBUaGUgd2VzdCBhbmNob3IgbWF5IGJlIHNldCB0byBhbiB7QGxpbmsgSW50ZWdlcn0gdmFsdWUKCSAqIGluZGljYXRpbmcgd2hlcmUgdGhlIHNuYXBwaW5nIGlzIG9jY3VycmluZy4gVGhpcyBpcyB1c2VkIGZvciBmZWVkYmFjawoJICogcHVycG9zZXMuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEtFWV9XRVNUX0FOQ0hPUiA9ICJTbmFwVG9HZW9tZXRyeS5XZXN0QW5jaG9yIjsgLy8kTk9OLU5MUy0xJAoKCS8qKgoJICogVGhlIGtleSB1c2VkIHRvIGlkZW50aWZ5IHRoZSBFYXN0IGFuY2hvciBwb2ludCBpbiB0aGUgZXh0ZW5kZWQgZGF0YSBvZiBhCgkgKiByZXF1ZXN0LiBUaGUgZWFzdCBhbmNob3IgbWF5IGJlIHNldCB0byBhbiB7QGxpbmsgSW50ZWdlcn0gdmFsdWUKCSAqIGluZGljYXRpbmcgd2hlcmUgdGhlIHNuYXBwaW5nIGlzIG9jY3VycmluZy4gVGhpcyBpcyB1c2VkIGZvciBmZWVkYmFjawoJICogcHVycG9zZXMuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEtFWV9FQVNUX0FOQ0hPUiA9ICJTbmFwVG9HZW9tZXRyeS5FYXN0QW5jaG9yIjsgLy8kTk9OLU5MUy0xJAoKCS8qKgoJICogQSB2ZXJ0aWNhbCBvciBob3Jpem9udGFsIHNuYXBwaW5nIHBvaW50LiBzaW5jZSAzLjAKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBjbGFzcyBFbnRyeSB7CgkJZmluYWwgaW50IHR5cGU7CgkJZmluYWwgaW50IGxvY2F0aW9uOwoKCQkvKioKCQkgKiBDb25zdHJ1Y3RzIGEgbmV3IGVudHJ5IG9mIHRoZSBnaXZlbiB0eXBlIGFuZCBsb2NhdGlvbi4KCQkgKiAKCQkgKiBAcGFyYW0gdHlwZQoJCSAqICAgICAgICAgICAgYW4gaW50ZWdlciBiZXR3ZWVuIC0xIGFuZCAxIGluY2x1c2l2ZWx5CgkJICogQHBhcmFtIGxvY2F0aW9uCgkJICogICAgICAgICAgICB0aGUgbG9jYXRpb24KCQkgKi8KCQlwcm90ZWN0ZWQgRW50cnkoaW50IHR5cGUsIGludCBsb2NhdGlvbikgewoJCQlpZiAodHlwZSA8IC0xIHx8IHR5cGUgPiAxKQoJCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVW5yZWNvZ25pemVkIHNuYXAgdHlwZSIpOyAvLyROT04tTkxTLTEkCgkJCXRoaXMudHlwZSA9IHR5cGU7CgkJCXRoaXMubG9jYXRpb24gPSBsb2NhdGlvbjsKCQl9CgoJCS8qKgoJCSAqIFJldHVybnMgdGhlIGxvY2F0aW9uIG9mIHRoZSBzbmFwIGVudHJ5LgoJCSAqIAoJCSAqIEByZXR1cm4gdGhlIGxvY2F0aW9uCgkJICogQHNpbmNlIDMuMgoJCSAqLwoJCXB1YmxpYyBpbnQgZ2V0TG9jYXRpb24oKSB7CgkJCXJldHVybiBsb2NhdGlvbjsKCQl9CgoJCS8qKgoJCSAqIFJldHVybnMgdGhlIHNuYXAgdHlwZS4gVGhlIGZvbGxvd2luZyB2YWx1ZXMgbWF5IGJlIHJldHVybmVkLgoJCSAqIDxVTD4KCQkgKiA8TEk+LTEgaW5kaWNhdGVzIGxlZnQvdG9wCgkJICogPExJPjAgaW5kaWNhdGVzIG1pZGRsZS9jZW50ZXIKCQkgKiA8TEk+MSBpbmRpY2F0ZXMgcmlnaHQvYm90dG9tCgkJICogPC9VTD4KCQkgKiAKCQkgKiBAcmV0dXJuIHRoZSBzbmFwIHR5cGUKCQkgKiBAc2luY2UgMy4yCgkJICovCgkJcHVibGljIGludCBnZXRUeXBlKCkgewoJCQlyZXR1cm4gdHlwZTsKCQl9Cgl9CgoJLyoqCgkgKiBUaGUgc2Vuc2l0aXZpdHkgb2YgdGhlIHNuYXBwaW5nLiBDb3JyZWN0aW9ucyBncmVhdGVyIHRoYW4gdGhpcyB2YWx1ZSB3aWxsCgkgKiBub3Qgb2NjdXIuCgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgZG91YmxlIFRIUkVTSE9MRCA9IDUuMDAwMTsKCglwcml2YXRlIGRvdWJsZSB0aHJlc2hvbGQgPSBUSFJFU0hPTEQ7CgoJYm9vbGVhbiBjYWNoZWRDbG9uZUJvb2w7CgoJLyoqCgkgKiBUaGUgaG9yaXpvbnRhbCByb3dzIGJlaW5nIHNuYXBwZWQgdG8uCgkgKi8KCXByb3RlY3RlZCBFbnRyeSByb3dzW107CgoJLyoqCgkgKiBUaGUgdmVydGljYWwgY29sdW1uZCBiZWluZyBzbmFwcGVkIHRvLgoJICovCglwcm90ZWN0ZWQgRW50cnkgY29sc1tdOwoKCS8qKgoJICogVGhlIGNvbnRhaW5lciBlZGl0cGFydCBwcm92aWRpbmcgdGhlIGNvb3JkaW5hdGVzIGFuZCB0aGUgY2hpbGRyZW4gdG8KCSAqIHdoaWNoIHNuYXBwaW5nIG9jY3Vycy4KCSAqLwoJcHJvdGVjdGVkIEdyYXBoaWNhbEVkaXRQYXJ0IGNvbnRhaW5lcjsKCgkvKioKCSAqIENvbnN0cnVjdHMgYSBoZWxwZXIgdGhhdCB3aWxsIHVzZSB0aGUgZ2l2ZW4gcGFydCBhcyBpdHMgYmFzaXMgZm9yCgkgKiBzbmFwcGluZy4gVGhlIHBhcnQncyBjb250ZW50cyBwYW5lIHdpbGwgcHJvdmlkZSB0aGUgY29vcmRpbmF0ZSBzeXN0ZW0gYW5kCgkgKiBpdHMgY2hpbGRyZW4gZGV0ZXJtaW5lIHRoZSBleGlzdGluZyBlbGVtZW50cy4KCSAqIAoJICogQHNpbmNlIDMuMAoJICogQHBhcmFtIGNvbnRhaW5lcgoJICogICAgICAgICAgICB0aGUgY29udGFpbmVyIGVkaXRwYXJ0CgkgKi8KCXB1YmxpYyBTbmFwVG9HZW9tZXRyeShHcmFwaGljYWxFZGl0UGFydCBjb250YWluZXIpIHsKCQl0aGlzLmNvbnRhaW5lciA9IGNvbnRhaW5lcjsKCX0KCgkvKioKCSAqIEdldCB0aGUgc2Vuc2l0aXZpdHkgb2YgdGhlIHNuYXBwaW5nLiBDb3JyZWN0aW9ucyBncmVhdGVyIHRoYW4gdGhpcyB2YWx1ZQoJICogd2lsbCBub3Qgb2NjdXIuCgkgKiAKCSAqIEByZXR1cm4gdGhlIHNuYXBwaW5nIHRocmVzaG9sZAoJICogQHNpbmNlIDMuNAoJICovCglwcm90ZWN0ZWQgZG91YmxlIGdldFRocmVzaG9sZCgpIHsKCQlyZXR1cm4gdGhpcy50aHJlc2hvbGQ7Cgl9CgoJLyoqCgkgKiBTZXQgdGhlIHNlbnNpdGl2aXR5IG9mIHRoZSBzbmFwcGluZy4KCSAqIAoJICogQHNlZSAjZ2V0VGhyZXNob2xkKCkKCSAqIEBwYXJhbSBuZXdUaHJlc2hvbGQKCSAqICAgICAgICAgICAgdGhlIG5ldyBzbmFwcGluZyB0aHJlc2hvbGQKCSAqIEBzaW5jZSAzLjQKCSAqLwoJcHJvdGVjdGVkIHZvaWQgc2V0VGhyZXNob2xkKGRvdWJsZSBuZXdUaHJlc2hvbGQpIHsKCQl0aGlzLnRocmVzaG9sZCA9IG5ld1RocmVzaG9sZDsKCX0KCgkvKioKCSAqIEdlbmVyYXRlcyBhIGxpc3Qgb2YgcGFydHMgd2hpY2ggc2hvdWxkIGJlIHNuYXBwZWQgdG8uIFRoZSBsaXN0IGlzIHRoZQoJICogb3JpZ2luYWwgY2hpbGRyZW4sIG1pbnVzIHRoZSBnaXZlbiBleGNsdXNpb25zLCBtaW51cyBhbmQgY2hpbGRyZW4gd2hvc2UKCSAqIGZpZ3VyZXMgYXJlIG5vdCB2aXNpYmxlLgoJICogCgkgKiBAc2luY2UgMy4wCgkgKiBAcGFyYW0gZXhjbHVzaW9ucwoJICogICAgICAgICAgICB0aGUgY2hpbGRyZW4gdG8gZXhjbHVkZQoJICogQHJldHVybiBhIGxpc3Qgb2YgcGFydHMgd2hpY2ggc2hvdWxkIGJlIHNuYXBwZWQgdG8KCSAqLwoJcHJvdGVjdGVkIExpc3QgZ2VuZXJhdGVTbmFwUGFydHNMaXN0KExpc3QgZXhjbHVzaW9ucykgewoJCS8vIERvbid0IHNuYXAgdG8gYW55IGZpZ3VyZSB0aGF0IGlzIGJlaW5nIGRyYWdnZWQKCQlMaXN0IGNoaWxkcmVuID0gbmV3IEFycmF5TGlzdChjb250YWluZXIuZ2V0Q2hpbGRyZW4oKSk7CgkJY2hpbGRyZW4ucmVtb3ZlQWxsKGV4Y2x1c2lvbnMpOwoKCQkvLyBEb24ndCBzbmFwIHRvIGhpZGRlbiBmaWd1cmVzCgkJTGlzdCBoaWRkZW5DaGlsZHJlbiA9IG5ldyBBcnJheUxpc3QoKTsKCQlmb3IgKEl0ZXJhdG9yIGl0ZXIgPSBjaGlsZHJlbi5pdGVyYXRvcigpOyBpdGVyLmhhc05leHQoKTspIHsKCQkJR3JhcGhpY2FsRWRpdFBhcnQgY2hpbGQgPSAoR3JhcGhpY2FsRWRpdFBhcnQpIGl0ZXIubmV4dCgpOwoJCQlpZiAoIWNoaWxkLmdldEZpZ3VyZSgpLmlzVmlzaWJsZSgpKQoJCQkJaGlkZGVuQ2hpbGRyZW4uYWRkKGNoaWxkKTsKCQl9CgkJY2hpbGRyZW4ucmVtb3ZlQWxsKGhpZGRlbkNoaWxkcmVuKTsKCgkJcmV0dXJuIGNoaWxkcmVuOwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgY29ycmVjdGlvbiB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudHJpZXMgYW5kIHNpZGVzLiBEdXJpbmcgYQoJICogbW92ZSwgdGhlIGxlZnQsIHJpZ2h0LCBvciBjZW50ZXIgaXMgZnJlZSB0byBzbmFwIHRvIGEgbG9jYXRpb24uCgkgKiAKCSAqIEBwYXJhbSBlbnRyaWVzCgkgKiAgICAgICAgICAgIHRoZSBlbnRyaWVzCgkgKiBAcGFyYW0gZXh0ZW5kZWREYXRhCgkgKiAgICAgICAgICAgIHRoZSByZXF1ZXN0cyBleHRlbmRlZCBkYXRhCgkgKiBAcGFyYW0gdmVydAoJICogICAgICAgICAgICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgY29ycmVjdGlvbiBpcyB2ZXJ0aWNhbAoJICogQHBhcmFtIG5lYXIKCSAqICAgICAgICAgICAgdGhlIGxlZnQvdG9wIHNpZGUgb2YgdGhlIHJlY3RhbmdsZQoJICogQHBhcmFtIGZhcgoJICogICAgICAgICAgICB0aGUgcmlnaHQvYm90dG9tIHNpZGUgb2YgdGhlIHJlY3RhbmdsZQoJICogQHJldHVybiB0aGUgY29ycmVjdGlvbiBhbW91bnQgb3IgI2dldFRocmVzaG9sZCAoKSBpZiBubyBjb3JyZWN0aW9uIHdhcwoJICogICAgICAgICBtYWRlCgkgKi8KCXByb3RlY3RlZCBkb3VibGUgZ2V0Q29ycmVjdGlvbkZvcihFbnRyeSBlbnRyaWVzW10sIE1hcCBleHRlbmRlZERhdGEsCgkJCWJvb2xlYW4gdmVydCwgZG91YmxlIG5lYXIsIGRvdWJsZSBmYXIpIHsKCQlmYXIgLT0gMS4wOwoJCWRvdWJsZSB0b3RhbCA9IG5lYXIgKyBmYXI7CgkJLy8gSWYgdGhlIHdpZHRoIGlzIGV2ZW4gKGkuZS4sIG9kZCByaWdodCBub3cgYmVjYXVzZSB3ZSBoYXZlIHJlZHVjZWQgb25lCgkJLy8gcGl4ZWwgZnJvbQoJCS8vIGZhcikgdGhlcmUgaXMgbm8gbWlkZGxlIHBpeGVsIHNvIGZhdm9yIHRoZSBsZWZ0LW1vc3QvdG9wLW1vc3QgcGl4ZWwKCQkvLyAod2hpY2ggaXMgd2hhdAoJCS8vIHBvcHVsYXRlUm93c0FuZENvbHMoKSBkb2VzIGJ5IHVzaW5nIGludCBwcmVjaXNpb24pLgoJCWlmICgoaW50KSAobmVhciAtIGZhcikgJSAyICE9IDApCgkJCXRvdGFsIC09IDEuMDsKCQlkb3VibGUgcmVzdWx0ID0gZ2V0Q29ycmVjdGlvbkZvcihlbnRyaWVzLCBleHRlbmRlZERhdGEsIHZlcnQsCgkJCQl0b3RhbCAvIDIsIDApOwoJCWlmIChyZXN1bHQgPT0gZ2V0VGhyZXNob2xkKCkpCgkJCXJlc3VsdCA9IGdldENvcnJlY3Rpb25Gb3IoZW50cmllcywgZXh0ZW5kZWREYXRhLCB2ZXJ0LCBuZWFyLCAtMSk7CgkJaWYgKHJlc3VsdCA9PSBnZXRUaHJlc2hvbGQoKSkKCQkJcmVzdWx0ID0gZ2V0Q29ycmVjdGlvbkZvcihlbnRyaWVzLCBleHRlbmRlZERhdGEsIHZlcnQsIGZhciwgMSk7CgkJcmV0dXJuIHJlc3VsdDsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIGNvcnJlY3Rpb24gdmFsdWUgYmV0d2VlbiCxIHtAbGluayAjZ2V0VGhyZXNob2xkKCl9LCBvciB0aGUKCSAqICNnZXRUaHJlc2hvbGQgKCkgaWYgbm8gY29ycmVjdGlvbnMgd2VyZSBmb3VuZC4KCSAqIAoJICogQHBhcmFtIGVudHJpZXMKCSAqICAgICAgICAgICAgdGhlIGVudHJpZXMKCSAqIEBwYXJhbSBleHRlbmRlZERhdGEKCSAqICAgICAgICAgICAgdGhlIG1hcCBmb3Igc2V0dGluZyB2YWx1ZXMKCSAqIEBwYXJhbSB2ZXJ0CgkgKiAgICAgICAgICAgIDxjb2RlPnRydWU8L2NvZGU+IGlmIHZlcnRpY2FsCgkgKiBAcGFyYW0gdmFsdWUKCSAqICAgICAgICAgICAgdGhlIHZhbHVlIGJlaW5nIGNvcnJlY3RlZAoJICogQHBhcmFtIHNpZGUKCSAqICAgICAgICAgICAgd2hpY2ggc2lkZXMgc2hvdWxkIGJlIGNvbnNpZGVyZWQKCSAqIEByZXR1cm4gdGhlIGNvcnJlY3Rpb24gb3IgI2dldFRocmVzaG9sZCAoKSBpZiBubyBjb3JyZWN0aW9uIHdhcyBtYWRlCgkgKi8KCXByb3RlY3RlZCBkb3VibGUgZ2V0Q29ycmVjdGlvbkZvcihFbnRyeSBlbnRyaWVzW10sIE1hcCBleHRlbmRlZERhdGEsCgkJCWJvb2xlYW4gdmVydCwgZG91YmxlIHZhbHVlLCBpbnQgc2lkZSkgewoJCWRvdWJsZSByZXN1bHRNYWcgPSBnZXRUaHJlc2hvbGQoKTsKCQlkb3VibGUgcmVzdWx0ID0gZ2V0VGhyZXNob2xkKCk7CgoJCVN0cmluZyBwcm9wZXJ0eTsKCQlpZiAoc2lkZSA9PSAtMSkKCQkJcHJvcGVydHkgPSB2ZXJ0ID8gS0VZX1dFU1RfQU5DSE9SIDogS0VZX05PUlRIX0FOQ0hPUjsKCQllbHNlCgkJCXByb3BlcnR5ID0gdmVydCA/IEtFWV9FQVNUX0FOQ0hPUiA6IEtFWV9TT1VUSF9BTkNIT1I7CgoJCWZvciAoaW50IGkgPSAwOyBpIDwgZW50cmllcy5sZW5ndGg7IGkrKykgewoJCQlFbnRyeSBlbnRyeSA9IGVudHJpZXNbaV07CgkJCWRvdWJsZSBtYWduaXR1ZGU7CgoJCQlpZiAoZW50cnkudHlwZSA9PSAtMSAmJiBzaWRlICE9IDApIHsKCQkJCW1hZ25pdHVkZSA9IE1hdGguYWJzKHZhbHVlIC0gZW50cnkubG9jYXRpb24pOwoJCQkJaWYgKG1hZ25pdHVkZSA8IHJlc3VsdE1hZykgewoJCQkJCXJlc3VsdE1hZyA9IG1hZ25pdHVkZTsKCQkJCQlyZXN1bHQgPSBlbnRyeS5sb2NhdGlvbiAtIHZhbHVlOwoJCQkJCWV4dGVuZGVkRGF0YS5wdXQocHJvcGVydHksIG5ldyBJbnRlZ2VyKGVudHJ5LmxvY2F0aW9uKSk7CgkJCQl9CgkJCX0gZWxzZSBpZiAoZW50cnkudHlwZSA9PSAwICYmIHNpZGUgPT0gMCkgewoJCQkJbWFnbml0dWRlID0gTWF0aC5hYnModmFsdWUgLSBlbnRyeS5sb2NhdGlvbik7CgkJCQlpZiAobWFnbml0dWRlIDwgcmVzdWx0TWFnKSB7CgkJCQkJcmVzdWx0TWFnID0gbWFnbml0dWRlOwoJCQkJCXJlc3VsdCA9IGVudHJ5LmxvY2F0aW9uIC0gdmFsdWU7CgkJCQkJZXh0ZW5kZWREYXRhLnB1dChwcm9wZXJ0eSwgbmV3IEludGVnZXIoZW50cnkubG9jYXRpb24pKTsKCQkJCX0KCQkJfSBlbHNlIGlmIChlbnRyeS50eXBlID09IDEgJiYgc2lkZSAhPSAwKSB7CgkJCQltYWduaXR1ZGUgPSBNYXRoLmFicyh2YWx1ZSAtIGVudHJ5LmxvY2F0aW9uKTsKCQkJCWlmIChtYWduaXR1ZGUgPCByZXN1bHRNYWcpIHsKCQkJCQlyZXN1bHRNYWcgPSBtYWduaXR1ZGU7CgkJCQkJcmVzdWx0ID0gZW50cnkubG9jYXRpb24gLSB2YWx1ZTsKCQkJCQlleHRlbmRlZERhdGEucHV0KHByb3BlcnR5LCBuZXcgSW50ZWdlcihlbnRyeS5sb2NhdGlvbikpOwoJCQkJfQoJCQl9CgkJfQoJCXJldHVybiByZXN1bHQ7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSByZWN0YW5ndWxhciBjb250cmlidXRpb24gZm9yIHRoZSBnaXZlbiBlZGl0cGFydC4gVGhpcyBpcyB0aGUKCSAqIHJlY3RhbmdsZSB3aXRoIHdoaWNoIHNuYXBwaW5nIGlzIHBlcmZvcm1lZC4KCSAqIAoJICogQHNpbmNlIDMuMAoJICogQHBhcmFtIHBhcnQKCSAqICAgICAgICAgICAgdGhlIGNoaWxkCgkgKiBAcmV0dXJuIHRoZSByZWN0YW5ndWxhciBndWlkZSBmb3IgdGhhdCBwYXJ0CgkgKi8KCXByb3RlY3RlZCBSZWN0YW5nbGUgZ2V0RmlndXJlQm91bmRzKEdyYXBoaWNhbEVkaXRQYXJ0IHBhcnQpIHsKCQlJRmlndXJlIGZpZyA9IHBhcnQuZ2V0RmlndXJlKCk7CgkJaWYgKGZpZyBpbnN0YW5jZW9mIEhhbmRsZUJvdW5kcykKCQkJcmV0dXJuICgoSGFuZGxlQm91bmRzKSBmaWcpLmdldEhhbmRsZUJvdW5kcygpOwoJCXJldHVybiBmaWcuZ2V0Qm91bmRzKCk7Cgl9CgoJLyoqCgkgKiBVcGRhdGVzIHRoZSBjYWNoZWQgcm93IGFuZCBjb2x1bW4gRW50cmllcyB1c2luZyB0aGUgcHJvdmlkZWQgcGFydHMuCgkgKiAKCSAqIEBzaW5jZSAzLjAKCSAqIEBwYXJhbSBwYXJ0cwoJICogICAgICAgICAgICBhIExpc3Qgb2YgRWRpdFBhcnRzCgkgKi8KCXByb3RlY3RlZCB2b2lkIHBvcHVsYXRlUm93c0FuZENvbHMoTGlzdCBwYXJ0cykgewoJCXJvd3MgPSBuZXcgRW50cnlbcGFydHMuc2l6ZSgpICogM107CgkJY29scyA9IG5ldyBFbnRyeVtwYXJ0cy5zaXplKCkgKiAzXTsKCQlmb3IgKGludCBpID0gMDsgaSA8IHBhcnRzLnNpemUoKTsgaSsrKSB7CgkJCUdyYXBoaWNhbEVkaXRQYXJ0IGNoaWxkID0gKEdyYXBoaWNhbEVkaXRQYXJ0KSBwYXJ0cy5nZXQoaSk7CgkJCVJlY3RhbmdsZSBib3VuZHMgPSBnZXRGaWd1cmVCb3VuZHMoY2hpbGQpOwoJCQljb2xzW2kgKiAzXSA9IG5ldyBFbnRyeSgtMSwgYm91bmRzLngpOwoJCQlyb3dzW2kgKiAzXSA9IG5ldyBFbnRyeSgtMSwgYm91bmRzLnkpOwoJCQljb2xzW2kgKiAzICsgMV0gPSBuZXcgRW50cnkoMCwgYm91bmRzLnggKyAoYm91bmRzLndpZHRoIC0gMSkgLyAyKTsKCQkJcm93c1tpICogMyArIDFdID0gbmV3IEVudHJ5KDAsIGJvdW5kcy55ICsgKGJvdW5kcy5oZWlnaHQgLSAxKSAvIDIpOwoJCQljb2xzW2kgKiAzICsgMl0gPSBuZXcgRW50cnkoMSwgYm91bmRzLnJpZ2h0KCkgLSAxKTsKCQkJcm93c1tpICogMyArIDJdID0gbmV3IEVudHJ5KDEsIGJvdW5kcy5ib3R0b20oKSAtIDEpOwoJCX0KCX0KCgkvKioKCSAqIEBzZWUgU25hcFRvSGVscGVyI3NuYXBSZWN0YW5nbGUoUmVxdWVzdCwgaW50LCBQcmVjaXNpb25SZWN0YW5nbGUsCgkgKiAgICAgIFByZWNpc2lvblJlY3RhbmdsZSkKCSAqLwoJcHVibGljIGludCBzbmFwUmVjdGFuZ2xlKFJlcXVlc3QgcmVxdWVzdCwgaW50IHNuYXBPcmllbnRhdGlvbiwKCQkJUHJlY2lzaW9uUmVjdGFuZ2xlIGJhc2VSZWN0LCBQcmVjaXNpb25SZWN0YW5nbGUgcmVzdWx0KSB7CgoJCWJhc2VSZWN0ID0gYmFzZVJlY3QuZ2V0UHJlY2lzZUNvcHkoKTsKCQltYWtlUmVsYXRpdmUoY29udGFpbmVyLmdldENvbnRlbnRQYW5lKCksIGJhc2VSZWN0KTsKCQlQcmVjaXNpb25SZWN0YW5nbGUgY29ycmVjdGlvbiA9IG5ldyBQcmVjaXNpb25SZWN0YW5nbGUoKTsKCQltYWtlUmVsYXRpdmUoY29udGFpbmVyLmdldENvbnRlbnRQYW5lKCksIGNvcnJlY3Rpb24pOwoKCQkvLyBSZWNhbGN1bGF0ZSBzbmFwcGluZyBsb2NhdGlvbnMgaWYgbmVlZGVkCgkJYm9vbGVhbiBpc0Nsb25lID0gcmVxdWVzdC5nZXRUeXBlKCkuZXF1YWxzKFJlcXVlc3RDb25zdGFudHMuUkVRX0NMT05FKTsKCQlpZiAocm93cyA9PSBudWxsIHx8IGNvbHMgPT0gbnVsbCB8fCBpc0Nsb25lICE9IGNhY2hlZENsb25lQm9vbCkgewoJCQljYWNoZWRDbG9uZUJvb2wgPSBpc0Nsb25lOwoJCQlMaXN0IGV4Y2x1c2lvblNldCA9IENvbGxlY3Rpb25zLkVNUFRZX0xJU1Q7CgkJCWlmICghaXNDbG9uZSAmJiByZXF1ZXN0IGluc3RhbmNlb2YgR3JvdXBSZXF1ZXN0KQoJCQkJZXhjbHVzaW9uU2V0ID0gKChHcm91cFJlcXVlc3QpIHJlcXVlc3QpLmdldEVkaXRQYXJ0cygpOwoJCQlwb3B1bGF0ZVJvd3NBbmRDb2xzKGdlbmVyYXRlU25hcFBhcnRzTGlzdChleGNsdXNpb25TZXQpKTsKCQl9CgoJCWlmICgoc25hcE9yaWVudGF0aW9uICYgSE9SSVpPTlRBTCkgIT0gMCkgewoJCQlkb3VibGUgeGNvcnJlY3QgPSBnZXRUaHJlc2hvbGQoKTsKCQkJeGNvcnJlY3QgPSBnZXRDb3JyZWN0aW9uRm9yKGNvbHMsIHJlcXVlc3QuZ2V0RXh0ZW5kZWREYXRhKCksIHRydWUsCgkJCQkJYmFzZVJlY3QucHJlY2lzZVgoKSwgYmFzZVJlY3QucHJlY2lzZVJpZ2h0KCkpOwoJCQlpZiAoeGNvcnJlY3QgIT0gZ2V0VGhyZXNob2xkKCkpIHsKCQkJCXNuYXBPcmllbnRhdGlvbiAmPSB+SE9SSVpPTlRBTDsKCQkJCWNvcnJlY3Rpb24uc2V0UHJlY2lzZVgoY29ycmVjdGlvbi5wcmVjaXNlWCgpICsgeGNvcnJlY3QpOwoJCQl9CgkJfQoKCQlpZiAoKHNuYXBPcmllbnRhdGlvbiAmIFZFUlRJQ0FMKSAhPSAwKSB7CgkJCWRvdWJsZSB5Y29ycmVjdCA9IGdldFRocmVzaG9sZCgpOwoJCQl5Y29ycmVjdCA9IGdldENvcnJlY3Rpb25Gb3Iocm93cywgcmVxdWVzdC5nZXRFeHRlbmRlZERhdGEoKSwgZmFsc2UsCgkJCQkJYmFzZVJlY3QucHJlY2lzZVkoKSwgYmFzZVJlY3QucHJlY2lzZUJvdHRvbSgpKTsKCQkJaWYgKHljb3JyZWN0ICE9IGdldFRocmVzaG9sZCgpKSB7CgkJCQlzbmFwT3JpZW50YXRpb24gJj0gflZFUlRJQ0FMOwoJCQkJY29ycmVjdGlvbi5zZXRQcmVjaXNlWShjb3JyZWN0aW9uLnByZWNpc2VZKCkgKyB5Y29ycmVjdCk7CgkJCX0KCQl9CgoJCWlmICgoc25hcE9yaWVudGF0aW9uICYgRUFTVCkgIT0gMCkgewoJCQlkb3VibGUgcmlnaHRDb3JyZWN0aW9uID0gZ2V0Q29ycmVjdGlvbkZvcihjb2xzLAoJCQkJCXJlcXVlc3QuZ2V0RXh0ZW5kZWREYXRhKCksIHRydWUsCgkJCQkJYmFzZVJlY3QucHJlY2lzZVJpZ2h0KCkgLSAxLCAxKTsKCQkJaWYgKHJpZ2h0Q29ycmVjdGlvbiAhPSBnZXRUaHJlc2hvbGQoKSkgewoJCQkJc25hcE9yaWVudGF0aW9uICY9IH5FQVNUOwoJCQkJY29ycmVjdGlvbi5zZXRQcmVjaXNlV2lkdGgoY29ycmVjdGlvbi5wcmVjaXNlV2lkdGgoKQoJCQkJCQkrIHJpZ2h0Q29ycmVjdGlvbik7CgkJCX0KCQl9CgoJCWlmICgoc25hcE9yaWVudGF0aW9uICYgV0VTVCkgIT0gMCkgewoJCQlkb3VibGUgbGVmdENvcnJlY3Rpb24gPSBnZXRDb3JyZWN0aW9uRm9yKGNvbHMsCgkJCQkJcmVxdWVzdC5nZXRFeHRlbmRlZERhdGEoKSwgdHJ1ZSwgYmFzZVJlY3QucHJlY2lzZVgoKSwgLTEpOwoJCQlpZiAobGVmdENvcnJlY3Rpb24gIT0gZ2V0VGhyZXNob2xkKCkpIHsKCQkJCXNuYXBPcmllbnRhdGlvbiAmPSB+V0VTVDsKCQkJCWNvcnJlY3Rpb24uc2V0UHJlY2lzZVdpZHRoKGNvcnJlY3Rpb24ucHJlY2lzZVdpZHRoKCkKCQkJCQkJLSBsZWZ0Q29ycmVjdGlvbik7CgkJCQljb3JyZWN0aW9uLnNldFByZWNpc2VYKGNvcnJlY3Rpb24ucHJlY2lzZVgoKSArIGxlZnRDb3JyZWN0aW9uKTsKCQkJfQoJCX0KCgkJaWYgKChzbmFwT3JpZW50YXRpb24gJiBTT1VUSCkgIT0gMCkgewoJCQlkb3VibGUgYm90dG9tID0gZ2V0Q29ycmVjdGlvbkZvcihyb3dzLCByZXF1ZXN0LmdldEV4dGVuZGVkRGF0YSgpLAoJCQkJCWZhbHNlLCBiYXNlUmVjdC5wcmVjaXNlQm90dG9tKCkgLSAxLCAxKTsKCQkJaWYgKGJvdHRvbSAhPSBnZXRUaHJlc2hvbGQoKSkgewoJCQkJc25hcE9yaWVudGF0aW9uICY9IH5TT1VUSDsKCQkJCWNvcnJlY3Rpb24KCQkJCQkJLnNldFByZWNpc2VIZWlnaHQoY29ycmVjdGlvbi5wcmVjaXNlSGVpZ2h0KCkgKyBib3R0b20pOwoJCQl9CgkJfQoKCQlpZiAoKHNuYXBPcmllbnRhdGlvbiAmIE5PUlRIKSAhPSAwKSB7CgkJCWRvdWJsZSB0b3BDb3JyZWN0aW9uID0gZ2V0Q29ycmVjdGlvbkZvcihyb3dzLAoJCQkJCXJlcXVlc3QuZ2V0RXh0ZW5kZWREYXRhKCksIGZhbHNlLCBiYXNlUmVjdC5wcmVjaXNlWSgpLCAtMSk7CgkJCWlmICh0b3BDb3JyZWN0aW9uICE9IGdldFRocmVzaG9sZCgpKSB7CgkJCQlzbmFwT3JpZW50YXRpb24gJj0gfk5PUlRIOwoJCQkJY29ycmVjdGlvbi5zZXRQcmVjaXNlSGVpZ2h0KGNvcnJlY3Rpb24ucHJlY2lzZUhlaWdodCgpCgkJCQkJCS0gdG9wQ29ycmVjdGlvbik7CgkJCQljb3JyZWN0aW9uLnNldFByZWNpc2VZKGNvcnJlY3Rpb24ucHJlY2lzZVkoKSArIHRvcENvcnJlY3Rpb24pOwoJCQl9CgkJfQoKCQltYWtlQWJzb2x1dGUoY29udGFpbmVyLmdldENvbnRlbnRQYW5lKCksIGNvcnJlY3Rpb24pOwoJCXJlc3VsdC5zZXRQcmVjaXNlWChyZXN1bHQucHJlY2lzZVgoKSArIGNvcnJlY3Rpb24ucHJlY2lzZVgoKSk7CgkJcmVzdWx0LnNldFByZWNpc2VZKHJlc3VsdC5wcmVjaXNlWSgpICsgY29ycmVjdGlvbi5wcmVjaXNlWSgpKTsKCQlyZXN1bHQuc2V0UHJlY2lzZVdpZHRoKHJlc3VsdC5wcmVjaXNlV2lkdGgoKQoJCQkJKyBjb3JyZWN0aW9uLnByZWNpc2VXaWR0aCgpKTsKCQlyZXN1bHQuc2V0UHJlY2lzZUhlaWdodChyZXN1bHQucHJlY2lzZUhlaWdodCgpCgkJCQkrIGNvcnJlY3Rpb24ucHJlY2lzZUhlaWdodCgpKTsKCQlyZXR1cm4gc25hcE9yaWVudGF0aW9uOwoJfQoKfQo=