LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKgogKiBDb250cmlidXRvcnM6CiAqICAgIElCTSBDb3Jwb3JhdGlvbiAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS53c3QuaW50ZXJuZXQubW9uaXRvci5jb3JlLmludGVybmFsOwoKaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CgppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLkNvcmVFeGNlcHRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVN0YXR1czsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5QcmVmZXJlbmNlczsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5TdGF0dXM7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QuaW50ZXJuZXQubW9uaXRvci5jb3JlLio7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QuaW50ZXJuZXQubW9uaXRvci5jb3JlLmludGVybmFsLmh0dHAuUmVzZW5kSFRUUFJlcXVlc3Q7Ci8qKgogKiAKICovCnB1YmxpYyBjbGFzcyBNb25pdG9yTWFuYWdlciB7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQUREID0gMDsKCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDSEFOR0UgPSAxOwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFJFTU9WRSA9IDI7CgoJLy8gbW9uaXRvcnMKCXByb3RlY3RlZCBMaXN0IG1vbml0b3JzOwoJcHJvdGVjdGVkIE1hcCB0aHJlYWRzID0gbmV3IEhhc2hNYXAoKTsKCQoJcHJvdGVjdGVkIExpc3QgbW9uaXRvckxpc3RlbmVycyA9IG5ldyBBcnJheUxpc3QoKTsKCglwcml2YXRlIFByZWZlcmVuY2VzLklQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIHBjbDsKCXByb3RlY3RlZCBib29sZWFuIGlnbm9yZVByZWZlcmVuY2VDaGFuZ2VzID0gZmFsc2U7CgkKCXByb3RlY3RlZCBNYXAgcmVzZW5kTWFwID0gbmV3IEhhc2hNYXAoKTsKCQoJcHJvdGVjdGVkIHN0YXRpYyBNb25pdG9yTWFuYWdlciBpbnN0YW5jZTsKCQoJc3RhdGljIHsKCQlNb25pdG9yUGx1Z2luLmdldEluc3RhbmNlKCkuZXhlY3V0ZVN0YXJ0dXBzKCk7Cgl9CgkKCXB1YmxpYyBzdGF0aWMgTW9uaXRvck1hbmFnZXIgZ2V0SW5zdGFuY2UoKSB7CgkJaWYgKGluc3RhbmNlID09IG51bGwpCgkJCWluc3RhbmNlID0gbmV3IE1vbml0b3JNYW5hZ2VyKCk7CgkKCQlyZXR1cm4gaW5zdGFuY2U7Cgl9CgkKCXByaXZhdGUgTW9uaXRvck1hbmFnZXIoKSB7CgkJbG9hZE1vbml0b3JzKCk7CgkJCgkJcGNsID0gbmV3IFByZWZlcmVuY2VzLklQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKCkgewoJCQlwdWJsaWMgdm9pZCBwcm9wZXJ0eUNoYW5nZShQcmVmZXJlbmNlcy5Qcm9wZXJ0eUNoYW5nZUV2ZW50IGV2ZW50KSB7CgkJCQlpZiAoaWdub3JlUHJlZmVyZW5jZUNoYW5nZXMpCgkJCQkJcmV0dXJuOwoJCQkJU3RyaW5nIHByb3BlcnR5ID0gZXZlbnQuZ2V0UHJvcGVydHkoKTsKCQkJCWlmIChwcm9wZXJ0eS5lcXVhbHMoIm1vbml0b3JzIikpIHsKCQkJCQlsb2FkTW9uaXRvcnMoKTsKCQkJCX0KCQkJfQoJCX07CgkJCgkJTW9uaXRvclBsdWdpbi5nZXRJbnN0YW5jZSgpLmdldFBsdWdpblByZWZlcmVuY2VzKCkuYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihwY2wpOwoJfQoJCglwcm90ZWN0ZWQgdm9pZCBkaXNwb3NlKCkgewoJCU1vbml0b3JQbHVnaW4uZ2V0SW5zdGFuY2UoKS5nZXRQbHVnaW5QcmVmZXJlbmNlcygpLnJlbW92ZVByb3BlcnR5Q2hhbmdlTGlzdGVuZXIocGNsKTsKCX0KCQoJcHVibGljIElNb25pdG9yV29ya2luZ0NvcHkgY3JlYXRlTW9uaXRvcigpIHsKCQlyZXR1cm4gbmV3IE1vbml0b3JXb3JraW5nQ29weSgpOwoJfQoJCglwdWJsaWMgTGlzdCBnZXRNb25pdG9ycygpIHsKCQlyZXR1cm4gbmV3IEFycmF5TGlzdChtb25pdG9ycyk7Cgl9CgoJcHJvdGVjdGVkIHN5bmNocm9uaXplZCB2b2lkIGFkZE1vbml0b3IoSU1vbml0b3IgbW9uaXRvcikgewoJCWlmICghbW9uaXRvcnMuY29udGFpbnMobW9uaXRvcikpCgkJCW1vbml0b3JzLmFkZChtb25pdG9yKTsKCQlmaXJlTW9uaXRvckV2ZW50KG1vbml0b3IsIEFERCk7CgkJc2F2ZU1vbml0b3JzKCk7Cgl9CgkKCXByb3RlY3RlZCBib29sZWFuIGlzUnVubmluZyhJTW9uaXRvciBtb25pdG9yKSB7CgkJcmV0dXJuICh0aHJlYWRzLmdldChtb25pdG9yKSAhPSBudWxsKTsKCX0KCglwdWJsaWMgdm9pZCBzdGFydE1vbml0b3IoSU1vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCWlmICghbW9uaXRvcnMuY29udGFpbnMobW9uaXRvcikpCgkJCXJldHVybjsKCQkKCQlpZiAoQWNjZXB0VGhyZWFkLmlzUG9ydEluVXNlKG1vbml0b3IuZ2V0TG9jYWxQb3J0KCkpKQoJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIE1vbml0b3JQbHVnaW4uUExVR0lOX0lELCAwLCBNb25pdG9yUGx1Z2luLmdldFJlc291cmNlKCIlZXJyb3JQb3J0SW5Vc2UiLCBtb25pdG9yLmdldExvY2FsUG9ydCgpICsgIiIpLCBudWxsKSk7CgkJCgkJQWNjZXB0VGhyZWFkIHRocmVhZCA9IG5ldyBBY2NlcHRUaHJlYWQobW9uaXRvcik7CgkJdGhyZWFkLnN0YXJ0U2VydmVyKCk7CgkJdGhyZWFkcy5wdXQobW9uaXRvciwgdGhyZWFkKTsKCX0KCQoJcHVibGljIHZvaWQgc3RvcE1vbml0b3IoSU1vbml0b3IgbW9uaXRvcikgewoJCWlmICghbW9uaXRvcnMuY29udGFpbnMobW9uaXRvcikpCgkJCXJldHVybjsKCQkKCQlBY2NlcHRUaHJlYWQgdGhyZWFkID0gKEFjY2VwdFRocmVhZCkgdGhyZWFkcy5nZXQobW9uaXRvcik7CgkJaWYgKHRocmVhZCAhPSBudWxsKSB7CgkJCXRocmVhZC5zdG9wU2VydmVyKCk7CgkJCXRocmVhZHMucmVtb3ZlKG1vbml0b3IpOwoJCX0KCX0KCQoJcHJvdGVjdGVkIHN5bmNocm9uaXplZCB2b2lkIHJlbW92ZU1vbml0b3IoSU1vbml0b3IgbW9uaXRvcikgewoJCWlmIChtb25pdG9yLmlzUnVubmluZygpKQoJCQlzdG9wTW9uaXRvcihtb25pdG9yKTsKCQltb25pdG9ycy5yZW1vdmUobW9uaXRvcik7CgkJZmlyZU1vbml0b3JFdmVudChtb25pdG9yLCBSRU1PVkUpOwoJCXNhdmVNb25pdG9ycygpOwoJfQoJCglwcm90ZWN0ZWQgc3luY2hyb25pemVkIHZvaWQgbW9uaXRvckNoYW5nZWQoSU1vbml0b3IgbW9uaXRvcikgewoJCWZpcmVNb25pdG9yRXZlbnQobW9uaXRvciwgQ0hBTkdFKTsKCQlzYXZlTW9uaXRvcnMoKTsKCX0KCQoJcHJvdGVjdGVkIGJvb2xlYW4gZXhpc3RzKElNb25pdG9yIG1vbml0b3IpIHsKCQlyZXR1cm4gKG1vbml0b3JzLmNvbnRhaW5zKG1vbml0b3IpKTsKCX0KCQoJLyoqCgkgKiBBZGQgbW9uaXRvciBsaXN0ZW5lci4KCSAqIAoJICogQHBhcmFtIGxpc3RlbmVyCgkgKi8KCXB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhZGRNb25pdG9yTGlzdGVuZXIoSU1vbml0b3JMaXN0ZW5lciBsaXN0ZW5lcikgewoJCWlmICghbW9uaXRvckxpc3RlbmVycy5jb250YWlucyhsaXN0ZW5lcikpCgkJCW1vbml0b3JMaXN0ZW5lcnMuYWRkKGxpc3RlbmVyKTsKCX0KCgkvKioKCSAqIFJlbW92ZSBtb25pdG9yIGxpc3RlbmVyLgoJICogCgkgKiBAcGFyYW0gbGlzdGVuZXIKCSAqLwoJcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHJlbW92ZU1vbml0b3JMaXN0ZW5lcihJTW9uaXRvckxpc3RlbmVyIGxpc3RlbmVyKSB7CgkJaWYgKG1vbml0b3JMaXN0ZW5lcnMuY29udGFpbnMobGlzdGVuZXIpKQoJCQltb25pdG9yTGlzdGVuZXJzLnJlbW92ZShsaXN0ZW5lcik7Cgl9CgkKCS8qKgoJICogRmlyZSBhIG1vbml0b3IgZXZlbnQuCgkgKiAKCSAqIEBwYXJhbSBtb25pdG9yIHRoZSBtb25pdG9yCgkgKiBAcGFyYW0gdHlwZSB0aGUgdHlwZSBvZiBldmVudAoJICovCglwcm90ZWN0ZWQgdm9pZCBmaXJlTW9uaXRvckV2ZW50KElNb25pdG9yIG1vbml0b3IsIGludCB0eXBlKSB7CgkJT2JqZWN0W10gb2JqID0gbW9uaXRvckxpc3RlbmVycy50b0FycmF5KCk7CgkJCgkJaW50IHNpemUgPSBvYmoubGVuZ3RoOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCUlNb25pdG9yTGlzdGVuZXIgbGlzdGVuZXIgPSAoSU1vbml0b3JMaXN0ZW5lcikgb2JqW2ldOwoJCQlpZiAodHlwZSA9PSBBREQpCgkJCQlsaXN0ZW5lci5tb25pdG9yQWRkZWQobW9uaXRvcik7CgkJCWVsc2UgaWYgKHR5cGUgPT0gQ0hBTkdFKQoJCQkJbGlzdGVuZXIubW9uaXRvckNoYW5nZWQobW9uaXRvcik7CgkJCWVsc2UgaWYgKHR5cGUgPT0gUkVNT1ZFKQoJCQkJbGlzdGVuZXIubW9uaXRvclJlbW92ZWQobW9uaXRvcik7CgkJfQoJfQoKCXByb3RlY3RlZCBzeW5jaHJvbml6ZWQgdm9pZCBsb2FkTW9uaXRvcnMoKSB7CgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiTG9hZGluZyBtb25pdG9ycyIpOwoJCQoJCW1vbml0b3JzID0gbmV3IEFycmF5TGlzdCgpOwoJCVByZWZlcmVuY2VzIHByZWZzID0gTW9uaXRvclBsdWdpbi5nZXRJbnN0YW5jZSgpLmdldFBsdWdpblByZWZlcmVuY2VzKCk7CgkJU3RyaW5nIHhtbFN0cmluZyA9IHByZWZzLmdldFN0cmluZygibW9uaXRvcnMiKTsKCQlpZiAoeG1sU3RyaW5nICE9IG51bGwgJiYgeG1sU3RyaW5nLmxlbmd0aCgpID4gMCkgewoJCQl0cnkgewoJCQkJQnl0ZUFycmF5SW5wdXRTdHJlYW0gaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oeG1sU3RyaW5nLmdldEJ5dGVzKCJVVEYtOCIpKTsKCQkJCUlNZW1lbnRvIG1lbWVudG8gPSBYTUxNZW1lbnRvLmxvYWRNZW1lbnRvKGluKTsKCQkKCQkJCUlNZW1lbnRvW10gY2hpbGRyZW4gPSBtZW1lbnRvLmdldENoaWxkcmVuKCJtb25pdG9yIik7CgkJCQlpZiAoY2hpbGRyZW4gIT0gbnVsbCkgewoJCQkJCWludCBzaXplID0gY2hpbGRyZW4ubGVuZ3RoOwoJCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQkJCU1vbml0b3IgbW9uaXRvciA9IG5ldyBNb25pdG9yKCk7CgkJCQkJCW1vbml0b3IubG9hZChjaGlsZHJlbltpXSk7CgkJCQkJCW1vbml0b3JzLmFkZChtb25pdG9yKTsKCQkJCQl9CgkJCQl9CgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5XQVJOSU5HLCAiQ291bGQgbm90IGxvYWQgbW9uaXRvcnM6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CgkJCX0KCQl9Cgl9CgkKCXByb3RlY3RlZCBzeW5jaHJvbml6ZWQgdm9pZCBzYXZlTW9uaXRvcnMoKSB7CgkJdHJ5IHsKCQkJaWdub3JlUHJlZmVyZW5jZUNoYW5nZXMgPSB0cnVlOwoJCQlYTUxNZW1lbnRvIG1lbWVudG8gPSBYTUxNZW1lbnRvLmNyZWF0ZVdyaXRlUm9vdCgibW9uaXRvcnMiKTsKCgkJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gbW9uaXRvcnMuaXRlcmF0b3IoKTsKCQkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQkJTW9uaXRvciBtb25pdG9yID0gKE1vbml0b3IpIGl0ZXJhdG9yLm5leHQoKTsKCQkJCUlNZW1lbnRvIGNoaWxkID0gbWVtZW50by5jcmVhdGVDaGlsZCgibW9uaXRvciIpOwoJCQkJbW9uaXRvci5zYXZlKGNoaWxkKTsKCQkJfQoJCQkKCQkJU3RyaW5nIHhtbFN0cmluZyA9IG1lbWVudG8uc2F2ZVRvU3RyaW5nKCk7CgkJCVByZWZlcmVuY2VzIHByZWZzID0gTW9uaXRvclBsdWdpbi5nZXRJbnN0YW5jZSgpLmdldFBsdWdpblByZWZlcmVuY2VzKCk7CgkJCXByZWZzLnNldFZhbHVlKCJtb25pdG9ycyIsIHhtbFN0cmluZyk7CgkJCU1vbml0b3JQbHVnaW4uZ2V0SW5zdGFuY2UoKS5zYXZlUGx1Z2luUHJlZmVyZW5jZXMoKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJDb3VsZCBub3Qgc2F2ZSBicm93c2VycyIsIGUpOwoJCX0KCQlpZ25vcmVQcmVmZXJlbmNlQ2hhbmdlcyA9IGZhbHNlOwoJfQoJCgkvKioKCSAqIENyZWF0ZXMgYSBuZXcgcmVzZW5kIHJlcXVlc3QgZnJvbSB0aGUgZ2l2ZW4gcmVxdWVzdC4KCSAqIAoJICogQHBhcmFtIHJlcXVlc3QgdGhlIHJlcXVlc3QgdGhhdCBpcyB0byBiZSByZXNlbnQ7IG1heSBub3QgYmUgPGNvZGU+bnVsbDwvY29kZT4KCSAqIEByZXR1cm4gYSBuZXcgcmVzZW5kIHJlcXVlc3QKCSAqLwoJcHVibGljIHN0YXRpYyBSZXNlbmRIVFRQUmVxdWVzdCBjcmVhdGVSZXNlbmRSZXF1ZXN0KFJlcXVlc3QgcmVxdWVzdCkgewoJCWlmIChyZXF1ZXN0ID09IG51bGwpCgkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKCQlyZXR1cm4gbmV3IFJlc2VuZEhUVFBSZXF1ZXN0KChNb25pdG9yKXJlcXVlc3QuZ2V0TW9uaXRvcigpLCByZXF1ZXN0KTsKCX0KCgkvKioKCSAqIEFkZHMgYSByZXNlbmQgcmVxdWVzdCB0byB0aGlzIHJlcXVlc3QuCgkgKiAKCSAqIEBwYXJhbSByZXF1ZXN0IHRoZSByZXNlbmQgcmVxdWVzdCB0byBhZGQKCSAqLwoJcHVibGljIHZvaWQgYWRkUmVzZW5kUmVxdWVzdChSZXF1ZXN0IHJlcXVlc3QsIFJlc2VuZEhUVFBSZXF1ZXN0IHJlc2VuZFJlcSkgewoJCWlmIChyZXF1ZXN0ID09IG51bGwgfHwgcmVzZW5kUmVxID09IG51bGwpCgkJCXJldHVybjsKCQkKCQlMaXN0IGxpc3QgPSBudWxsOwoJCXRyeSB7CgkJCWxpc3QgPSAoTGlzdCkgcmVzZW5kTWFwLmdldChyZXF1ZXN0KTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkvLyBpZ25vcmUKCQl9CgkJCgkJaWYgKGxpc3QgPT0gbnVsbCkgewoJCQlsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCQlyZXNlbmRNYXAucHV0KHJlcXVlc3QsIGxpc3QpOwoJCX0KCQlsaXN0LmFkZChyZXNlbmRSZXEpOwoJfQoKCS8qKgoJICogUmV0dXJucyBhbiBhcnJheSBvZiByZXNlbmQgcmVxdWVzdHMgYmFzZWQgb24gdGhpcyByZXF1ZXN0LiAKCSAqIAoJICogQHJldHVybiB0aGUgYXJyYXkgb2YgcmVzZW5kIHJlcXVlc3RzIGJhc2VkIG9uIHRoaXMgcmVxdWVzdAoJICovCglwdWJsaWMgUmVzZW5kSFRUUFJlcXVlc3RbXSBnZXRSZXNlbmRSZXF1ZXN0cyhSZXF1ZXN0IHJlcXVlc3QpIHsKCQl0cnkgewoJCQlMaXN0IGxpc3QgPSAoTGlzdCkgcmVzZW5kTWFwLmdldChyZXF1ZXN0KTsKCQkJUmVzZW5kSFRUUFJlcXVlc3RbXSByciA9IG5ldyBSZXNlbmRIVFRQUmVxdWVzdFtsaXN0LnNpemUoKV07CgkJCWxpc3QudG9BcnJheShycik7CgkJCXJldHVybiBycjsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlyZXR1cm4gbmV3IFJlc2VuZEhUVFBSZXF1ZXN0WzBdOwoJCX0KCX0KfQ==