LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA4IC0gMjAxMiBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCiAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQogKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wIGFuZCBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbi4KICogVGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgaXMgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCiAqIGFuZCB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSBpcyBhdmFpbGFibGUgYXQKICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgogKgogKiBDb250cmlidXRvcnM6CiAqICAgICBMaW5kYSBEZU1pY2hpZWwgLSBKYXZhIFBlcnNpc3RlbmNlIDIuMQogKiAgICAgTGluZGEgRGVNaWNoaWVsIC0gSmF2YSBQZXJzaXN0ZW5jZSAyLjAKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8gCnBhY2thZ2UgamF2YXgucGVyc2lzdGVuY2U7CgppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmF4LnBlcnNpc3RlbmNlLm1ldGFtb2RlbC5NZXRhbW9kZWw7CmltcG9ydCBqYXZheC5wZXJzaXN0ZW5jZS5jcml0ZXJpYS5Dcml0ZXJpYUJ1aWxkZXI7CmltcG9ydCBqYXZheC5wZXJzaXN0ZW5jZS5jcml0ZXJpYS5Dcml0ZXJpYVF1ZXJ5OwppbXBvcnQgamF2YXgucGVyc2lzdGVuY2UuY3JpdGVyaWEuQ3JpdGVyaWFVcGRhdGU7CmltcG9ydCBqYXZheC5wZXJzaXN0ZW5jZS5jcml0ZXJpYS5Dcml0ZXJpYURlbGV0ZTsKCi8qKgogKiBJbnRlcmZhY2UgdXNlZCB0byBpbnRlcmFjdCB3aXRoIHRoZSBwZXJzaXN0ZW5jZSBjb250ZXh0LgogKgogKiA8cD4gQW4gPGNvZGU+RW50aXR5TWFuYWdlcjwvY29kZT4gaW5zdGFuY2UgaXMgYXNzb2NpYXRlZCB3aXRoIAogKiBhIHBlcnNpc3RlbmNlIGNvbnRleHQuIEEgcGVyc2lzdGVuY2UgY29udGV4dCBpcyBhIHNldCBvZiBlbnRpdHkgCiAqIGluc3RhbmNlcyBpbiB3aGljaCBmb3IgYW55IHBlcnNpc3RlbnQgZW50aXR5IGlkZW50aXR5IHRoZXJlIGlzIAogKiBhIHVuaXF1ZSBlbnRpdHkgaW5zdGFuY2UuIFdpdGhpbiB0aGUgcGVyc2lzdGVuY2UgY29udGV4dCwgdGhlIAogKiBlbnRpdHkgaW5zdGFuY2VzIGFuZCB0aGVpciBsaWZlY3ljbGUgYXJlIG1hbmFnZWQuIAogKiBUaGUgPGNvZGU+RW50aXR5TWFuYWdlcjwvY29kZT4gQVBJIGlzIHVzZWQgCiAqIHRvIGNyZWF0ZSBhbmQgcmVtb3ZlIHBlcnNpc3RlbnQgZW50aXR5IGluc3RhbmNlcywgdG8gZmluZCBlbnRpdGllcyAKICogYnkgdGhlaXIgcHJpbWFyeSBrZXksIGFuZCB0byBxdWVyeSBvdmVyIGVudGl0aWVzLgogKgogKiA8cD4gVGhlIHNldCBvZiBlbnRpdGllcyB0aGF0IGNhbiBiZSBtYW5hZ2VkIGJ5IGEgZ2l2ZW4gCiAqIDxjb2RlPkVudGl0eU1hbmFnZXI8L2NvZGU+IGluc3RhbmNlIGlzIGRlZmluZWQgYnkgYSBwZXJzaXN0ZW5jZSAKICogdW5pdC4gQSBwZXJzaXN0ZW5jZSB1bml0IGRlZmluZXMgdGhlIHNldCBvZiBhbGwgY2xhc3NlcyB0aGF0IGFyZSAKICogcmVsYXRlZCBvciBncm91cGVkIGJ5IHRoZSBhcHBsaWNhdGlvbiwgYW5kIHdoaWNoIG11c3QgYmUgCiAqIGNvbG9jYXRlZCBpbiB0aGVpciBtYXBwaW5nIHRvIGEgc2luZ2xlIGRhdGFiYXNlLgogKgogKiBAc2VlIFF1ZXJ5CiAqIEBzZWUgVHlwZWRRdWVyeQogKiBAc2VlIENyaXRlcmlhUXVlcnkKICogQHNlZSBQZXJzaXN0ZW5jZUNvbnRleHQKICogQHNlZSBTdG9yZWRQcm9jZWR1cmVRdWVyeQogKiAKICogQHNpbmNlIEphdmEgUGVyc2lzdGVuY2UgMS4wCiAqLwpwdWJsaWMgaW50ZXJmYWNlIEVudGl0eU1hbmFnZXIgewoKICAgIC8qKgogICAgICogTWFrZSBhbiBpbnN0YW5jZSBtYW5hZ2VkIGFuZCBwZXJzaXN0ZW50LgogICAgICogQHBhcmFtIGVudGl0eSAgZW50aXR5IGluc3RhbmNlCiAgICAgKiBAdGhyb3dzIEVudGl0eUV4aXN0c0V4Y2VwdGlvbiBpZiB0aGUgZW50aXR5IGFscmVhZHkgZXhpc3RzLgogICAgICogKElmIHRoZSBlbnRpdHkgYWxyZWFkeSBleGlzdHMsIHRoZSA8Y29kZT5FbnRpdHlFeGlzdHNFeGNlcHRpb248L2NvZGU+IG1heSAKICAgICAqIGJlIHRocm93biB3aGVuIHRoZSBwZXJzaXN0IG9wZXJhdGlvbiBpcyBpbnZva2VkLCBvciB0aGUKICAgICAqIDxjb2RlPkVudGl0eUV4aXN0c0V4Y2VwdGlvbjwvY29kZT4gb3IgYW5vdGhlciA8Y29kZT5QZXJzaXN0ZW5jZUV4Y2VwdGlvbjwvY29kZT4gbWF5IGJlIAogICAgICogdGhyb3duIGF0IGZsdXNoIG9yIGNvbW1pdCB0aW1lLikgCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgaW5zdGFuY2UgaXMgbm90IGFuCiAgICAgKiAgICAgICAgIGVudGl0eQogICAgICogQHRocm93cyBUcmFuc2FjdGlvblJlcXVpcmVkRXhjZXB0aW9uIGlmIHRoZXJlIGlzIG5vIHRyYW5zYWN0aW9uIHdoZW4KICAgICAqICAgICAgICAgaW52b2tlZCBvbiBhIGNvbnRhaW5lci1tYW5hZ2VkIGVudGl0eSBtYW5hZ2VyIG9mIHRoYXQgaXMgb2YgdHlwZSAKICAgICAqICAgICAgICAgPGNvZGU+UGVyc2lzdGVuY2VDb250ZXh0VHlwZS5UUkFOU0FDVElPTjwvY29kZT4KICAgICAqLwogICAgcHVibGljIHZvaWQgcGVyc2lzdChPYmplY3QgZW50aXR5KTsKICAgIAogICAgLyoqCiAgICAgKiBNZXJnZSB0aGUgc3RhdGUgb2YgdGhlIGdpdmVuIGVudGl0eSBpbnRvIHRoZQogICAgICogY3VycmVudCBwZXJzaXN0ZW5jZSBjb250ZXh0LgogICAgICogQHBhcmFtIGVudGl0eSAgZW50aXR5IGluc3RhbmNlCiAgICAgKiBAcmV0dXJuIHRoZSBtYW5hZ2VkIGluc3RhbmNlIHRoYXQgdGhlIHN0YXRlIHdhcyBtZXJnZWQgdG8KICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGluc3RhbmNlIGlzIG5vdCBhbgogICAgICogICAgICAgICBlbnRpdHkgb3IgaXMgYSByZW1vdmVkIGVudGl0eQogICAgICogQHRocm93cyBUcmFuc2FjdGlvblJlcXVpcmVkRXhjZXB0aW9uIGlmIHRoZXJlIGlzIG5vIHRyYW5zYWN0aW9uIHdoZW4KICAgICAqICAgICAgICAgaW52b2tlZCBvbiBhIGNvbnRhaW5lci1tYW5hZ2VkIGVudGl0eSBtYW5hZ2VyIG9mIHRoYXQgaXMgb2YgdHlwZSAKICAgICAqICAgICAgICAgPGNvZGU+UGVyc2lzdGVuY2VDb250ZXh0VHlwZS5UUkFOU0FDVElPTjwvY29kZT4KICAgICAqLyAgICAKICAgIHB1YmxpYyA8VD4gVCBtZXJnZShUIGVudGl0eSk7CiAgICAKICAgIC8qKgogICAgICogUmVtb3ZlIHRoZSBlbnRpdHkgaW5zdGFuY2UuCiAgICAgKiBAcGFyYW0gZW50aXR5ICBlbnRpdHkgaW5zdGFuY2UKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBpbnN0YW5jZSBpcyBub3QgYW4KICAgICAqICAgICAgICAgZW50aXR5IG9yIGlzIGEgZGV0YWNoZWQgZW50aXR5CiAgICAgKiBAdGhyb3dzIFRyYW5zYWN0aW9uUmVxdWlyZWRFeGNlcHRpb24gaWYgaW52b2tlZCBvbiBhCiAgICAgKiAgICAgICAgIGNvbnRhaW5lci1tYW5hZ2VkIGVudGl0eSBtYW5hZ2VyIG9mIHR5cGUgCiAgICAgKiAgICAgICAgIDxjb2RlPlBlcnNpc3RlbmNlQ29udGV4dFR5cGUuVFJBTlNBQ1RJT048L2NvZGU+IGFuZCB0aGVyZSBpcyAKICAgICAqICAgICAgICAgbm8gdHJhbnNhY3Rpb24KICAgICAqLyAgICAKICAgIHB1YmxpYyB2b2lkIHJlbW92ZShPYmplY3QgZW50aXR5KTsKICAgIAogICAgLyoqCiAgICAgKiBGaW5kIGJ5IHByaW1hcnkga2V5LgogICAgICogU2VhcmNoIGZvciBhbiBlbnRpdHkgb2YgdGhlIHNwZWNpZmllZCBjbGFzcyBhbmQgcHJpbWFyeSBrZXkuCiAgICAgKiBJZiB0aGUgZW50aXR5IGluc3RhbmNlIGlzIGNvbnRhaW5lZCBpbiB0aGUgcGVyc2lzdGVuY2UgY29udGV4dCwKICAgICAqIGl0IGlzIHJldHVybmVkIGZyb20gdGhlcmUuCiAgICAgKiBAcGFyYW0gZW50aXR5Q2xhc3MgIGVudGl0eSBjbGFzcwogICAgICogQHBhcmFtIHByaW1hcnlLZXkgIHByaW1hcnkga2V5CiAgICAgKiBAcmV0dXJuIHRoZSBmb3VuZCBlbnRpdHkgaW5zdGFuY2Ugb3IgbnVsbCBpZiB0aGUgZW50aXR5IGRvZXMKICAgICAqICAgICAgICAgbm90IGV4aXN0CiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgZmlyc3QgYXJndW1lbnQgZG9lcwogICAgICogICAgICAgICBub3QgZGVub3RlIGFuIGVudGl0eSB0eXBlIG9yIHRoZSBzZWNvbmQgYXJndW1lbnQgaXMgCiAgICAgKiAgICAgICAgIGlzIG5vdCBhIHZhbGlkIHR5cGUgZm9yIHRoYXQgZW50aXR5knMgcHJpbWFyeSBrZXkgb3IKICAgICAqICAgICAgICAgaXMgbnVsbAogICAgICovCiAgICBwdWJsaWMgPFQ+IFQgZmluZChDbGFzczxUPiBlbnRpdHlDbGFzcywgT2JqZWN0IHByaW1hcnlLZXkpOwogICAgCiAgICAvKioKICAgICAqIEZpbmQgYnkgcHJpbWFyeSBrZXksIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy4gCiAgICAgKiBTZWFyY2ggZm9yIGFuIGVudGl0eSBvZiB0aGUgc3BlY2lmaWVkIGNsYXNzIGFuZCBwcmltYXJ5IGtleS4gCiAgICAgKiBJZiB0aGUgZW50aXR5IGluc3RhbmNlIGlzIGNvbnRhaW5lZCBpbiB0aGUgcGVyc2lzdGVuY2UgCiAgICAgKiBjb250ZXh0LCBpdCBpcyByZXR1cm5lZCBmcm9tIHRoZXJlLiAKICAgICAqIElmIGEgdmVuZG9yLXNwZWNpZmljIHByb3BlcnR5IG9yIGhpbnQgaXMgbm90IHJlY29nbml6ZWQsIAogICAgICogaXQgaXMgc2lsZW50bHkgaWdub3JlZC4gCiAgICAgKiBAcGFyYW0gZW50aXR5Q2xhc3MgIGVudGl0eSBjbGFzcwogICAgICogQHBhcmFtIHByaW1hcnlLZXkgICBwcmltYXJ5IGtleQogICAgICogQHBhcmFtIHByb3BlcnRpZXMgIHN0YW5kYXJkIGFuZCB2ZW5kb3Itc3BlY2lmaWMgcHJvcGVydGllcyAKICAgICAqICAgICAgICBhbmQgaGludHMKICAgICAqIEByZXR1cm4gdGhlIGZvdW5kIGVudGl0eSBpbnN0YW5jZSBvciBudWxsIGlmIHRoZSBlbnRpdHkgZG9lcwogICAgICogICAgICAgICBub3QgZXhpc3QgCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgZmlyc3QgYXJndW1lbnQgZG9lcyAKICAgICAqICAgICAgICAgbm90IGRlbm90ZSBhbiBlbnRpdHkgdHlwZSBvciB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzCiAgICAgKiAgICAgICAgIGlzIG5vdCBhIHZhbGlkIHR5cGUgZm9yIHRoYXQgZW50aXR5knMgcHJpbWFyeSBrZXkgb3IgCiAgICAgKiAgICAgICAgIGlzIG51bGwgCiAgICAgKiBAc2luY2UgSmF2YSBQZXJzaXN0ZW5jZSAyLjAKICAgICAqLyAKICAgIHB1YmxpYyA8VD4gVCBmaW5kKENsYXNzPFQ+IGVudGl0eUNsYXNzLCBPYmplY3QgcHJpbWFyeUtleSwgCiAgICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBPYmplY3Q+IHByb3BlcnRpZXMpOyAKICAgIAogICAgLyoqCiAgICAgKiBGaW5kIGJ5IHByaW1hcnkga2V5IGFuZCBsb2NrLgogICAgICogU2VhcmNoIGZvciBhbiBlbnRpdHkgb2YgdGhlIHNwZWNpZmllZCBjbGFzcyBhbmQgcHJpbWFyeSBrZXkKICAgICAqIGFuZCBsb2NrIGl0IHdpdGggcmVzcGVjdCB0byB0aGUgc3BlY2lmaWVkIGxvY2sgdHlwZS4KICAgICAqIElmIHRoZSBlbnRpdHkgaW5zdGFuY2UgaXMgY29udGFpbmVkIGluIHRoZSBwZXJzaXN0ZW5jZSBjb250ZXh0LAogICAgICogaXQgaXMgcmV0dXJuZWQgZnJvbSB0aGVyZSwgYW5kIHRoZSBlZmZlY3Qgb2YgdGhpcyBtZXRob2QgaXMKICAgICAqIHRoZSBzYW1lIGFzIGlmIHRoZSBsb2NrIG1ldGhvZCBoYWQgYmVlbiBjYWxsZWQgb24gdGhlIGVudGl0eS4KICAgICAqIDxwPiBJZiB0aGUgZW50aXR5IGlzIGZvdW5kIHdpdGhpbiB0aGUgcGVyc2lzdGVuY2UgY29udGV4dCBhbmQgdGhlCiAgICAgKiBsb2NrIG1vZGUgdHlwZSBpcyBwZXNzaW1pc3RpYyBhbmQgdGhlIGVudGl0eSBoYXMgYSB2ZXJzaW9uCiAgICAgKiBhdHRyaWJ1dGUsIHRoZSBwZXJzaXN0ZW5jZSBwcm92aWRlciBtdXN0IHBlcmZvcm0gb3B0aW1pc3RpYwogICAgICogdmVyc2lvbiBjaGVja3Mgd2hlbiBvYnRhaW5pbmcgdGhlIGRhdGFiYXNlIGxvY2suICBJZiB0aGVzZSAKICAgICAqIGNoZWNrcyBmYWlsLCB0aGUgPGNvZGU+T3B0aW1pc3RpY0xvY2tFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duLgogICAgICogPHA+SWYgdGhlIGxvY2sgbW9kZSB0eXBlIGlzIHBlc3NpbWlzdGljIGFuZCB0aGUgZW50aXR5IGluc3RhbmNlCiAgICAgKiBpcyBmb3VuZCBidXQgY2Fubm90IGJlIGxvY2tlZDoKICAgICAqIDx1bD4KICAgICAqIDxsaT4gdGhlIDxjb2RlPlBlc3NpbWlzdGljTG9ja0V4Y2VwdGlvbjwvY29kZT4gd2lsbCBiZSB0aHJvd24gaWYgdGhlIGRhdGFiYXNlCiAgICAgKiAgICBsb2NraW5nIGZhaWx1cmUgY2F1c2VzIHRyYW5zYWN0aW9uLWxldmVsIHJvbGxiYWNrCiAgICAgKiA8bGk+IHRoZSA8Y29kZT5Mb2NrVGltZW91dEV4Y2VwdGlvbjwvY29kZT4gd2lsbCBiZSB0aHJvd24gaWYgdGhlIGRhdGFiYXNlCiAgICAgKiAgICBsb2NraW5nIGZhaWx1cmUgY2F1c2VzIG9ubHkgc3RhdGVtZW50LWxldmVsIHJvbGxiYWNrCiAgICAgKiA8L3VsPgogICAgICogQHBhcmFtIGVudGl0eUNsYXNzICBlbnRpdHkgY2xhc3MKICAgICAqIEBwYXJhbSBwcmltYXJ5S2V5ICBwcmltYXJ5IGtleQogICAgICogQHBhcmFtIGxvY2tNb2RlICBsb2NrIG1vZGUKICAgICAqIEByZXR1cm4gdGhlIGZvdW5kIGVudGl0eSBpbnN0YW5jZSBvciBudWxsIGlmIHRoZSBlbnRpdHkgZG9lcwogICAgICogICAgICAgICBub3QgZXhpc3QKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBmaXJzdCBhcmd1bWVudCBkb2VzCiAgICAgKiAgICAgICAgIG5vdCBkZW5vdGUgYW4gZW50aXR5IHR5cGUgb3IgdGhlIHNlY29uZCBhcmd1bWVudCBpcyAKICAgICAqICAgICAgICAgbm90IGEgdmFsaWQgdHlwZSBmb3IgdGhhdCBlbnRpdHkncyBwcmltYXJ5IGtleSBvciAKICAgICAqICAgICAgICAgaXMgbnVsbAogICAgICogQHRocm93cyBUcmFuc2FjdGlvblJlcXVpcmVkRXhjZXB0aW9uIGlmIHRoZXJlIGlzIG5vIAogICAgICogICAgICAgICB0cmFuc2FjdGlvbiBhbmQgYSBsb2NrIG1vZGUgb3RoZXIgdGhhbiA8Y29kZT5OT05FPC9jb2RlPiBpcwogICAgICogICAgICAgICBzcGVjaWZpZWQgb3IgaWYgaW52b2tlZCBvbiBhbiBlbnRpdHkgbWFuYWdlciB3aGljaCBoYXMKICAgICAqICAgICAgICAgbm90IGJlZW4gam9pbmVkIHRvIHRoZSBjdXJyZW50IHRyYW5zYWN0aW9uIGFuZCBhIGxvY2sKICAgICAqICAgICAgICAgbW9kZSBvdGhlciB0aGFuIDxjb2RlPk5PTkU8L2NvZGU+IGlzIHNwZWNpZmllZAogICAgICogQHRocm93cyBPcHRpbWlzdGljTG9ja0V4Y2VwdGlvbiBpZiB0aGUgb3B0aW1pc3RpYyB2ZXJzaW9uIAogICAgICogICAgICAgICBjaGVjayBmYWlscwogICAgICogQHRocm93cyBQZXNzaW1pc3RpY0xvY2tFeGNlcHRpb24gaWYgcGVzc2ltaXN0aWMgbG9ja2luZyAKICAgICAqICAgICAgICAgZmFpbHMgYW5kIHRoZSB0cmFuc2FjdGlvbiBpcyByb2xsZWQgYmFjawogICAgICogQHRocm93cyBMb2NrVGltZW91dEV4Y2VwdGlvbiBpZiBwZXNzaW1pc3RpYyBsb2NraW5nIGZhaWxzIGFuZAogICAgICogICAgICAgICBvbmx5IHRoZSBzdGF0ZW1lbnQgaXMgcm9sbGVkIGJhY2sKICAgICAqIEB0aHJvd3MgUGVyc2lzdGVuY2VFeGNlcHRpb24gaWYgYW4gdW5zdXBwb3J0ZWQgbG9jayBjYWxsIAogICAgICogICAgICAgICBpcyBtYWRlCiAgICAgKiBAc2luY2UgSmF2YSBQZXJzaXN0ZW5jZSAyLjAKICAgICAqLwogICAgcHVibGljIDxUPiBUIGZpbmQoQ2xhc3M8VD4gZW50aXR5Q2xhc3MsIE9iamVjdCBwcmltYXJ5S2V5LAogICAgICAgICAgICAgICAgICAgICAgTG9ja01vZGVUeXBlIGxvY2tNb2RlKTsKCiAgICAvKioKICAgICAqIEZpbmQgYnkgcHJpbWFyeSBrZXkgYW5kIGxvY2ssIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy4gCiAgICAgKiBTZWFyY2ggZm9yIGFuIGVudGl0eSBvZiB0aGUgc3BlY2lmaWVkIGNsYXNzIGFuZCBwcmltYXJ5IGtleQogICAgICogYW5kIGxvY2sgaXQgd2l0aCByZXNwZWN0IHRvIHRoZSBzcGVjaWZpZWQgbG9jayB0eXBlLgogICAgICogSWYgdGhlIGVudGl0eSBpbnN0YW5jZSBpcyBjb250YWluZWQgaW4gdGhlIHBlcnNpc3RlbmNlIGNvbnRleHQsCiAgICAgKiBpdCBpcyByZXR1cm5lZCBmcm9tIHRoZXJlLiAgCiAgICAgKiA8cD4gSWYgdGhlIGVudGl0eSBpcyBmb3VuZAogICAgICogd2l0aGluIHRoZSBwZXJzaXN0ZW5jZSBjb250ZXh0IGFuZCB0aGUgbG9jayBtb2RlIHR5cGUKICAgICAqIGlzIHBlc3NpbWlzdGljIGFuZCB0aGUgZW50aXR5IGhhcyBhIHZlcnNpb24gYXR0cmlidXRlLCB0aGUKICAgICAqIHBlcnNpc3RlbmNlIHByb3ZpZGVyIG11c3QgcGVyZm9ybSBvcHRpbWlzdGljIHZlcnNpb24gY2hlY2tzCiAgICAgKiB3aGVuIG9idGFpbmluZyB0aGUgZGF0YWJhc2UgbG9jay4gIElmIHRoZXNlIGNoZWNrcyBmYWlsLAogICAgICogdGhlIDxjb2RlPk9wdGltaXN0aWNMb2NrRXhjZXB0aW9uPC9jb2RlPiB3aWxsIGJlIHRocm93bi4KICAgICAqIDxwPklmIHRoZSBsb2NrIG1vZGUgdHlwZSBpcyBwZXNzaW1pc3RpYyBhbmQgdGhlIGVudGl0eSBpbnN0YW5jZQogICAgICogaXMgZm91bmQgYnV0IGNhbm5vdCBiZSBsb2NrZWQ6CiAgICAgKiA8dWw+CiAgICAgKiA8bGk+IHRoZSA8Y29kZT5QZXNzaW1pc3RpY0xvY2tFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duIGlmIHRoZSBkYXRhYmFzZQogICAgICogICAgbG9ja2luZyBmYWlsdXJlIGNhdXNlcyB0cmFuc2FjdGlvbi1sZXZlbCByb2xsYmFjawogICAgICogPGxpPiB0aGUgPGNvZGU+TG9ja1RpbWVvdXRFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duIGlmIHRoZSBkYXRhYmFzZQogICAgICogICAgbG9ja2luZyBmYWlsdXJlIGNhdXNlcyBvbmx5IHN0YXRlbWVudC1sZXZlbCByb2xsYmFjawogICAgICogPC91bD4KICAgICAqIDxwPklmIGEgdmVuZG9yLXNwZWNpZmljIHByb3BlcnR5IG9yIGhpbnQgaXMgbm90IHJlY29nbml6ZWQsIAogICAgICogaXQgaXMgc2lsZW50bHkgaWdub3JlZC4gIAogICAgICogPHA+UG9ydGFibGUgYXBwbGljYXRpb25zIHNob3VsZCBub3QgcmVseSBvbiB0aGUgc3RhbmRhcmQgdGltZW91dAogICAgICogaGludC4gRGVwZW5kaW5nIG9uIHRoZSBkYXRhYmFzZSBpbiB1c2UgYW5kIHRoZSBsb2NraW5nCiAgICAgKiBtZWNoYW5pc21zIHVzZWQgYnkgdGhlIHByb3ZpZGVyLCB0aGUgaGludCBtYXkgb3IgbWF5IG5vdAogICAgICogYmUgb2JzZXJ2ZWQuCiAgICAgKiBAcGFyYW0gZW50aXR5Q2xhc3MgIGVudGl0eSBjbGFzcwogICAgICogQHBhcmFtIHByaW1hcnlLZXkgIHByaW1hcnkga2V5CiAgICAgKiBAcGFyYW0gbG9ja01vZGUgIGxvY2sgbW9kZQogICAgICogQHBhcmFtIHByb3BlcnRpZXMgIHN0YW5kYXJkIGFuZCB2ZW5kb3Itc3BlY2lmaWMgcHJvcGVydGllcwogICAgICogICAgICAgIGFuZCBoaW50cwogICAgICogQHJldHVybiB0aGUgZm91bmQgZW50aXR5IGluc3RhbmNlIG9yIG51bGwgaWYgdGhlIGVudGl0eSBkb2VzCiAgICAgKiAgICAgICAgIG5vdCBleGlzdAogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGZpcnN0IGFyZ3VtZW50IGRvZXMKICAgICAqICAgICAgICAgbm90IGRlbm90ZSBhbiBlbnRpdHkgdHlwZSBvciB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIAogICAgICogICAgICAgICBub3QgYSB2YWxpZCB0eXBlIGZvciB0aGF0IGVudGl0eSdzIHByaW1hcnkga2V5IG9yIAogICAgICogICAgICAgICBpcyBudWxsCiAgICAgKiBAdGhyb3dzIFRyYW5zYWN0aW9uUmVxdWlyZWRFeGNlcHRpb24gaWYgdGhlcmUgaXMgbm8gCiAgICAgKiAgICAgICAgIHRyYW5zYWN0aW9uIGFuZCBhIGxvY2sgbW9kZSBvdGhlciB0aGFuIDxjb2RlPk5PTkU8L2NvZGU+IGlzCiAgICAgKiAgICAgICAgIHNwZWNpZmllZCBvciBpZiBpbnZva2VkIG9uIGFuIGVudGl0eSBtYW5hZ2VyIHdoaWNoIGhhcwogICAgICogICAgICAgICBub3QgYmVlbiBqb2luZWQgdG8gdGhlIGN1cnJlbnQgdHJhbnNhY3Rpb24gYW5kIGEgbG9jawogICAgICogICAgICAgICBtb2RlIG90aGVyIHRoYW4gPGNvZGU+Tk9ORTwvY29kZT4gaXMgc3BlY2lmaWVkCiAgICAgKiBAdGhyb3dzIE9wdGltaXN0aWNMb2NrRXhjZXB0aW9uIGlmIHRoZSBvcHRpbWlzdGljIHZlcnNpb24gCiAgICAgKiAgICAgICAgIGNoZWNrIGZhaWxzCiAgICAgKiBAdGhyb3dzIFBlc3NpbWlzdGljTG9ja0V4Y2VwdGlvbiBpZiBwZXNzaW1pc3RpYyBsb2NraW5nIAogICAgICogICAgICAgICBmYWlscyBhbmQgdGhlIHRyYW5zYWN0aW9uIGlzIHJvbGxlZCBiYWNrCiAgICAgKiBAdGhyb3dzIExvY2tUaW1lb3V0RXhjZXB0aW9uIGlmIHBlc3NpbWlzdGljIGxvY2tpbmcgZmFpbHMgYW5kCiAgICAgKiAgICAgICAgIG9ubHkgdGhlIHN0YXRlbWVudCBpcyByb2xsZWQgYmFjawogICAgICogQHRocm93cyBQZXJzaXN0ZW5jZUV4Y2VwdGlvbiBpZiBhbiB1bnN1cHBvcnRlZCBsb2NrIGNhbGwgCiAgICAgKiAgICAgICAgIGlzIG1hZGUKICAgICAqIEBzaW5jZSBKYXZhIFBlcnNpc3RlbmNlIDIuMAogICAgICovCiAgICBwdWJsaWMgPFQ+IFQgZmluZChDbGFzczxUPiBlbnRpdHlDbGFzcywgT2JqZWN0IHByaW1hcnlLZXksCiAgICAgICAgICAgICAgICAgICAgICBMb2NrTW9kZVR5cGUgbG9ja01vZGUsIAogICAgICAgICAgICAgICAgICAgICAgTWFwPFN0cmluZywgT2JqZWN0PiBwcm9wZXJ0aWVzKTsKCiAgICAvKioKICAgICAqIEdldCBhbiBpbnN0YW5jZSwgd2hvc2Ugc3RhdGUgbWF5IGJlIGxhemlseSBmZXRjaGVkLgogICAgICogSWYgdGhlIHJlcXVlc3RlZCBpbnN0YW5jZSBkb2VzIG5vdCBleGlzdCBpbiB0aGUgZGF0YWJhc2UsCiAgICAgKiB0aGUgPGNvZGU+RW50aXR5Tm90Rm91bmRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93biB3aGVuIHRoZSBpbnN0YW5jZSAKICAgICAqIHN0YXRlIGlzIGZpcnN0IGFjY2Vzc2VkLiAoVGhlIHBlcnNpc3RlbmNlIHByb3ZpZGVyIHJ1bnRpbWUgaXMgCiAgICAgKiBwZXJtaXR0ZWQgdG8gdGhyb3cgdGhlIDxjb2RlPkVudGl0eU5vdEZvdW5kRXhjZXB0aW9uPC9jb2RlPiB3aGVuIAogICAgICogPGNvZGU+Z2V0UmVmZXJlbmNlPC9jb2RlPiBpcyBjYWxsZWQuKQogICAgICogVGhlIGFwcGxpY2F0aW9uIHNob3VsZCBub3QgZXhwZWN0IHRoYXQgdGhlIGluc3RhbmNlIHN0YXRlIHdpbGwKICAgICAqIGJlIGF2YWlsYWJsZSB1cG9uIGRldGFjaG1lbnQsIHVubGVzcyBpdCB3YXMgYWNjZXNzZWQgYnkgdGhlCiAgICAgKiBhcHBsaWNhdGlvbiB3aGlsZSB0aGUgZW50aXR5IG1hbmFnZXIgd2FzIG9wZW4uCiAgICAgKiBAcGFyYW0gZW50aXR5Q2xhc3MgIGVudGl0eSBjbGFzcwogICAgICogQHBhcmFtIHByaW1hcnlLZXkgIHByaW1hcnkga2V5CiAgICAgKiBAcmV0dXJuIHRoZSBmb3VuZCBlbnRpdHkgaW5zdGFuY2UKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBmaXJzdCBhcmd1bWVudCBkb2VzCiAgICAgKiAgICAgICAgIG5vdCBkZW5vdGUgYW4gZW50aXR5IHR5cGUgb3IgdGhlIHNlY29uZCBhcmd1bWVudCBpcwogICAgICogICAgICAgICBub3QgYSB2YWxpZCB0eXBlIGZvciB0aGF0IGVudGl0eSdzIHByaW1hcnkga2V5IG9yCiAgICAgKiAgICAgICAgIGlzIG51bGwKICAgICAqIEB0aHJvd3MgRW50aXR5Tm90Rm91bmRFeGNlcHRpb24gaWYgdGhlIGVudGl0eSBzdGF0ZSAKICAgICAqICAgICAgICAgY2Fubm90IGJlIGFjY2Vzc2VkCiAgICAgKi8KICAgIHB1YmxpYyA8VD4gVCBnZXRSZWZlcmVuY2UoQ2xhc3M8VD4gZW50aXR5Q2xhc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHByaW1hcnlLZXkpOwoKICAgIC8qKgogICAgICogU3luY2hyb25pemUgdGhlIHBlcnNpc3RlbmNlIGNvbnRleHQgdG8gdGhlCiAgICAgKiB1bmRlcmx5aW5nIGRhdGFiYXNlLgogICAgICogQHRocm93cyBUcmFuc2FjdGlvblJlcXVpcmVkRXhjZXB0aW9uIGlmIHRoZXJlIGlzCiAgICAgKiAgICAgICAgIG5vIHRyYW5zYWN0aW9uIG9yIGlmIHRoZSBlbnRpdHkgbWFuYWdlciBoYXMgbm90IGJlZW4KICAgICAqICAgICAgICAgam9pbmVkIHRvIHRoZSBjdXJyZW50IHRyYW5zYWN0aW9uCiAgICAgKiBAdGhyb3dzIFBlcnNpc3RlbmNlRXhjZXB0aW9uIGlmIHRoZSBmbHVzaCBmYWlscwogICAgICovCiAgICBwdWJsaWMgdm9pZCBmbHVzaCgpOwoKICAgIC8qKgogICAgICogU2V0IHRoZSBmbHVzaCBtb2RlIHRoYXQgYXBwbGllcyB0byBhbGwgb2JqZWN0cyBjb250YWluZWQKICAgICAqIGluIHRoZSBwZXJzaXN0ZW5jZSBjb250ZXh0LiAKICAgICAqIEBwYXJhbSBmbHVzaE1vZGUgIGZsdXNoIG1vZGUKICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0Rmx1c2hNb2RlKEZsdXNoTW9kZVR5cGUgZmx1c2hNb2RlKTsKCiAgICAvKioKICAgICAqIEdldCB0aGUgZmx1c2ggbW9kZSB0aGF0IGFwcGxpZXMgdG8gYWxsIG9iamVjdHMgY29udGFpbmVkCiAgICAgKiBpbiB0aGUgcGVyc2lzdGVuY2UgY29udGV4dC4gCiAgICAgKiBAcmV0dXJuIGZsdXNoTW9kZQogICAgICovCiAgICBwdWJsaWMgRmx1c2hNb2RlVHlwZSBnZXRGbHVzaE1vZGUoKTsKCiAgICAvKioKICAgICAqIExvY2sgYW4gZW50aXR5IGluc3RhbmNlIHRoYXQgaXMgY29udGFpbmVkIGluIHRoZSBwZXJzaXN0ZW5jZQogICAgICogY29udGV4dCB3aXRoIHRoZSBzcGVjaWZpZWQgbG9jayBtb2RlIHR5cGUuCiAgICAgKiA8cD5JZiBhIHBlc3NpbWlzdGljIGxvY2sgbW9kZSB0eXBlIGlzIHNwZWNpZmllZCBhbmQgdGhlIGVudGl0eQogICAgICogY29udGFpbnMgYSB2ZXJzaW9uIGF0dHJpYnV0ZSwgdGhlIHBlcnNpc3RlbmNlIHByb3ZpZGVyIG11c3QgCiAgICAgKiBhbHNvIHBlcmZvcm0gb3B0aW1pc3RpYyB2ZXJzaW9uIGNoZWNrcyB3aGVuIG9idGFpbmluZyB0aGUgCiAgICAgKiBkYXRhYmFzZSBsb2NrLiAgSWYgdGhlc2UgY2hlY2tzIGZhaWwsIHRoZSAKICAgICAqIDxjb2RlPk9wdGltaXN0aWNMb2NrRXhjZXB0aW9uPC9jb2RlPiB3aWxsIGJlIHRocm93bi4KICAgICAqIDxwPklmIHRoZSBsb2NrIG1vZGUgdHlwZSBpcyBwZXNzaW1pc3RpYyBhbmQgdGhlIGVudGl0eSBpbnN0YW5jZQogICAgICogaXMgZm91bmQgYnV0IGNhbm5vdCBiZSBsb2NrZWQ6CiAgICAgKiA8dWw+CiAgICAgKiA8bGk+IHRoZSA8Y29kZT5QZXNzaW1pc3RpY0xvY2tFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duIGlmIHRoZSBkYXRhYmFzZQogICAgICogICAgbG9ja2luZyBmYWlsdXJlIGNhdXNlcyB0cmFuc2FjdGlvbi1sZXZlbCByb2xsYmFjawogICAgICogPGxpPiB0aGUgPGNvZGU+TG9ja1RpbWVvdXRFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duIGlmIHRoZSBkYXRhYmFzZQogICAgICogICAgbG9ja2luZyBmYWlsdXJlIGNhdXNlcyBvbmx5IHN0YXRlbWVudC1sZXZlbCByb2xsYmFjawogICAgICogPC91bD4KICAgICAqIEBwYXJhbSBlbnRpdHkgIGVudGl0eSBpbnN0YW5jZQogICAgICogQHBhcmFtIGxvY2tNb2RlICBsb2NrIG1vZGUKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBpbnN0YW5jZSBpcyBub3QgYW4KICAgICAqICAgICAgICAgZW50aXR5IG9yIGlzIGEgZGV0YWNoZWQgZW50aXR5CiAgICAgKiBAdGhyb3dzIFRyYW5zYWN0aW9uUmVxdWlyZWRFeGNlcHRpb24gaWYgdGhlcmUgaXMgbm8gCiAgICAgKiAgICAgICAgIHRyYW5zYWN0aW9uIG9yIGlmIGludm9rZWQgb24gYW4gZW50aXR5IG1hbmFnZXIgd2hpY2gKICAgICAqICAgICAgICAgaGFzIG5vdCBiZWVuIGpvaW5lZCB0byB0aGUgY3VycmVudCB0cmFuc2FjdGlvbgogICAgICogQHRocm93cyBFbnRpdHlOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGUgZW50aXR5IGRvZXMgbm90IGV4aXN0IAogICAgICogICAgICAgICBpbiB0aGUgZGF0YWJhc2Ugd2hlbiBwZXNzaW1pc3RpYyBsb2NraW5nIGlzIAogICAgICogICAgICAgICBwZXJmb3JtZWQKICAgICAqIEB0aHJvd3MgT3B0aW1pc3RpY0xvY2tFeGNlcHRpb24gaWYgdGhlIG9wdGltaXN0aWMgdmVyc2lvbiAKICAgICAqICAgICAgICAgY2hlY2sgZmFpbHMKICAgICAqIEB0aHJvd3MgUGVzc2ltaXN0aWNMb2NrRXhjZXB0aW9uIGlmIHBlc3NpbWlzdGljIGxvY2tpbmcgZmFpbHMgCiAgICAgKiAgICAgICAgIGFuZCB0aGUgdHJhbnNhY3Rpb24gaXMgcm9sbGVkIGJhY2sKICAgICAqIEB0aHJvd3MgTG9ja1RpbWVvdXRFeGNlcHRpb24gaWYgcGVzc2ltaXN0aWMgbG9ja2luZyBmYWlscyBhbmQKICAgICAqICAgICAgICAgb25seSB0aGUgc3RhdGVtZW50IGlzIHJvbGxlZCBiYWNrCiAgICAgKiBAdGhyb3dzIFBlcnNpc3RlbmNlRXhjZXB0aW9uIGlmIGFuIHVuc3VwcG9ydGVkIGxvY2sgY2FsbCAKICAgICAqICAgICAgICAgaXMgbWFkZQogICAgICovCiAgICBwdWJsaWMgdm9pZCBsb2NrKE9iamVjdCBlbnRpdHksIExvY2tNb2RlVHlwZSBsb2NrTW9kZSk7CgogICAgLyoqCiAgICAgKiBMb2NrIGFuIGVudGl0eSBpbnN0YW5jZSB0aGF0IGlzIGNvbnRhaW5lZCBpbiB0aGUgcGVyc2lzdGVuY2UKICAgICAqIGNvbnRleHQgd2l0aCB0aGUgc3BlY2lmaWVkIGxvY2sgbW9kZSB0eXBlIGFuZCB3aXRoIHNwZWNpZmllZAogICAgICogcHJvcGVydGllcy4KICAgICAqIDxwPklmIGEgcGVzc2ltaXN0aWMgbG9jayBtb2RlIHR5cGUgaXMgc3BlY2lmaWVkIGFuZCB0aGUgZW50aXR5CiAgICAgKiBjb250YWlucyBhIHZlcnNpb24gYXR0cmlidXRlLCB0aGUgcGVyc2lzdGVuY2UgcHJvdmlkZXIgbXVzdCAKICAgICAqIGFsc28gcGVyZm9ybSBvcHRpbWlzdGljIHZlcnNpb24gY2hlY2tzIHdoZW4gb2J0YWluaW5nIHRoZSAKICAgICAqIGRhdGFiYXNlIGxvY2suICBJZiB0aGVzZSBjaGVja3MgZmFpbCwgdGhlIAogICAgICogPGNvZGU+T3B0aW1pc3RpY0xvY2tFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duLgogICAgICogPHA+SWYgdGhlIGxvY2sgbW9kZSB0eXBlIGlzIHBlc3NpbWlzdGljIGFuZCB0aGUgZW50aXR5IGluc3RhbmNlCiAgICAgKiBpcyBmb3VuZCBidXQgY2Fubm90IGJlIGxvY2tlZDoKICAgICAqIDx1bD4KICAgICAqIDxsaT4gdGhlIDxjb2RlPlBlc3NpbWlzdGljTG9ja0V4Y2VwdGlvbjwvY29kZT4gd2lsbCBiZSB0aHJvd24gaWYgdGhlIGRhdGFiYXNlCiAgICAgKiAgICBsb2NraW5nIGZhaWx1cmUgY2F1c2VzIHRyYW5zYWN0aW9uLWxldmVsIHJvbGxiYWNrCiAgICAgKiA8bGk+IHRoZSA8Y29kZT5Mb2NrVGltZW91dEV4Y2VwdGlvbjwvY29kZT4gd2lsbCBiZSB0aHJvd24gaWYgdGhlIGRhdGFiYXNlCiAgICAgKiAgICBsb2NraW5nIGZhaWx1cmUgY2F1c2VzIG9ubHkgc3RhdGVtZW50LWxldmVsIHJvbGxiYWNrCiAgICAgKiA8L3VsPgogICAgICogPHA+SWYgYSB2ZW5kb3Itc3BlY2lmaWMgcHJvcGVydHkgb3IgaGludCBpcyBub3QgcmVjb2duaXplZCwgCiAgICAgKiBpdCBpcyBzaWxlbnRseSBpZ25vcmVkLiAgCiAgICAgKiA8cD5Qb3J0YWJsZSBhcHBsaWNhdGlvbnMgc2hvdWxkIG5vdCByZWx5IG9uIHRoZSBzdGFuZGFyZCB0aW1lb3V0CiAgICAgKiBoaW50LiBEZXBlbmRpbmcgb24gdGhlIGRhdGFiYXNlIGluIHVzZSBhbmQgdGhlIGxvY2tpbmcKICAgICAqIG1lY2hhbmlzbXMgdXNlZCBieSB0aGUgcHJvdmlkZXIsIHRoZSBoaW50IG1heSBvciBtYXkgbm90CiAgICAgKiBiZSBvYnNlcnZlZC4KICAgICAqIEBwYXJhbSBlbnRpdHkgIGVudGl0eSBpbnN0YW5jZQogICAgICogQHBhcmFtIGxvY2tNb2RlICBsb2NrIG1vZGUKICAgICAqIEBwYXJhbSBwcm9wZXJ0aWVzICBzdGFuZGFyZCBhbmQgdmVuZG9yLXNwZWNpZmljIHByb3BlcnRpZXMKICAgICAqICAgICAgICBhbmQgaGludHMKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBpbnN0YW5jZSBpcyBub3QgYW4KICAgICAqICAgICAgICAgZW50aXR5IG9yIGlzIGEgZGV0YWNoZWQgZW50aXR5CiAgICAgKiBAdGhyb3dzIFRyYW5zYWN0aW9uUmVxdWlyZWRFeGNlcHRpb24gaWYgdGhlcmUgaXMgbm8gCiAgICAgKiAgICAgICAgIHRyYW5zYWN0aW9uIG9yIGlmIGludm9rZWQgb24gYW4gZW50aXR5IG1hbmFnZXIgd2hpY2gKICAgICAqICAgICAgICAgaGFzIG5vdCBiZWVuIGpvaW5lZCB0byB0aGUgY3VycmVudCB0cmFuc2FjdGlvbgogICAgICogQHRocm93cyBFbnRpdHlOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGUgZW50aXR5IGRvZXMgbm90IGV4aXN0IAogICAgICogICAgICAgICBpbiB0aGUgZGF0YWJhc2Ugd2hlbiBwZXNzaW1pc3RpYyBsb2NraW5nIGlzIAogICAgICogICAgICAgICBwZXJmb3JtZWQKICAgICAqIEB0aHJvd3MgT3B0aW1pc3RpY0xvY2tFeGNlcHRpb24gaWYgdGhlIG9wdGltaXN0aWMgdmVyc2lvbiAKICAgICAqICAgICAgICAgY2hlY2sgZmFpbHMKICAgICAqIEB0aHJvd3MgUGVzc2ltaXN0aWNMb2NrRXhjZXB0aW9uIGlmIHBlc3NpbWlzdGljIGxvY2tpbmcgZmFpbHMgCiAgICAgKiAgICAgICAgIGFuZCB0aGUgdHJhbnNhY3Rpb24gaXMgcm9sbGVkIGJhY2sKICAgICAqIEB0aHJvd3MgTG9ja1RpbWVvdXRFeGNlcHRpb24gaWYgcGVzc2ltaXN0aWMgbG9ja2luZyBmYWlscyBhbmQKICAgICAqICAgICAgICAgb25seSB0aGUgc3RhdGVtZW50IGlzIHJvbGxlZCBiYWNrCiAgICAgKiBAdGhyb3dzIFBlcnNpc3RlbmNlRXhjZXB0aW9uIGlmIGFuIHVuc3VwcG9ydGVkIGxvY2sgY2FsbCAKICAgICAqICAgICAgICAgaXMgbWFkZQogICAgICogQHNpbmNlIEphdmEgUGVyc2lzdGVuY2UgMi4wCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGxvY2soT2JqZWN0IGVudGl0eSwgTG9ja01vZGVUeXBlIGxvY2tNb2RlLAogICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBPYmplY3Q+IHByb3BlcnRpZXMpOwoKICAgIC8qKgogICAgICogUmVmcmVzaCB0aGUgc3RhdGUgb2YgdGhlIGluc3RhbmNlIGZyb20gdGhlIGRhdGFiYXNlLCAKICAgICAqIG92ZXJ3cml0aW5nIGNoYW5nZXMgbWFkZSB0byB0aGUgZW50aXR5LCBpZiBhbnkuIAogICAgICogQHBhcmFtIGVudGl0eSAgZW50aXR5IGluc3RhbmNlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgaW5zdGFuY2UgaXMgbm90CiAgICAgKiAgICAgICAgIGFuIGVudGl0eSBvciB0aGUgZW50aXR5IGlzIG5vdCBtYW5hZ2VkCiAgICAgKiBAdGhyb3dzIFRyYW5zYWN0aW9uUmVxdWlyZWRFeGNlcHRpb24gaWYgdGhlcmUgaXMgbm8KICAgICAqICAgICAgICAgdHJhbnNhY3Rpb24gd2hlbiBpbnZva2VkIG9uIGEgY29udGFpbmVyLW1hbmFnZWQKICAgICAqICAgICAgICAgZW50aXR5IG1hbmFnZXIgb2YgdHlwZSA8Y29kZT5QZXJzaXN0ZW5jZUNvbnRleHRUeXBlLlRSQU5TQUNUSU9OPC9jb2RlPgogICAgICogQHRocm93cyBFbnRpdHlOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGUgZW50aXR5IG5vIGxvbmdlcgogICAgICogICAgICAgICBleGlzdHMgaW4gdGhlIGRhdGFiYXNlCiAgICAgKi8gICAgCiAgICBwdWJsaWMgdm9pZCByZWZyZXNoKE9iamVjdCBlbnRpdHkpOwoKICAgIC8qKgogICAgICogUmVmcmVzaCB0aGUgc3RhdGUgb2YgdGhlIGluc3RhbmNlIGZyb20gdGhlIGRhdGFiYXNlLCB1c2luZyAKICAgICAqIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcywgYW5kIG92ZXJ3cml0aW5nIGNoYW5nZXMgbWFkZSB0bwogICAgICogdGhlIGVudGl0eSwgaWYgYW55LiAKICAgICAqIDxwPiBJZiBhIHZlbmRvci1zcGVjaWZpYyBwcm9wZXJ0eSBvciBoaW50IGlzIG5vdCByZWNvZ25pemVkLCAKICAgICAqIGl0IGlzIHNpbGVudGx5IGlnbm9yZWQuIAogICAgICogQHBhcmFtIGVudGl0eSAgZW50aXR5IGluc3RhbmNlCiAgICAgKiBAcGFyYW0gcHJvcGVydGllcyAgc3RhbmRhcmQgYW5kIHZlbmRvci1zcGVjaWZpYyBwcm9wZXJ0aWVzIAogICAgICogICAgICAgIGFuZCBoaW50cwogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGluc3RhbmNlIGlzIG5vdCAKICAgICAqICAgICAgICAgYW4gZW50aXR5IG9yIHRoZSBlbnRpdHkgaXMgbm90IG1hbmFnZWQgCiAgICAgKiBAdGhyb3dzIFRyYW5zYWN0aW9uUmVxdWlyZWRFeGNlcHRpb24gaWYgdGhlcmUgaXMgbm8KICAgICAqICAgICAgICAgdHJhbnNhY3Rpb24gd2hlbiBpbnZva2VkIG9uIGEgY29udGFpbmVyLW1hbmFnZWQKICAgICAqICAgICAgICAgZW50aXR5IG1hbmFnZXIgb2YgdHlwZSA8Y29kZT5QZXJzaXN0ZW5jZUNvbnRleHRUeXBlLlRSQU5TQUNUSU9OPC9jb2RlPgogICAgICogQHRocm93cyBFbnRpdHlOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGUgZW50aXR5IG5vIGxvbmdlciAKICAgICAqICAgICAgICAgZXhpc3RzIGluIHRoZSBkYXRhYmFzZSAKICAgICAqIEBzaW5jZSBKYXZhIFBlcnNpc3RlbmNlIDIuMAogICAgICovICAgICAKICAgIHB1YmxpYyB2b2lkIHJlZnJlc2goT2JqZWN0IGVudGl0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsIE9iamVjdD4gcHJvcGVydGllcyk7IAoKICAgIC8qKgogICAgICogUmVmcmVzaCB0aGUgc3RhdGUgb2YgdGhlIGluc3RhbmNlIGZyb20gdGhlIGRhdGFiYXNlLCAKICAgICAqIG92ZXJ3cml0aW5nIGNoYW5nZXMgbWFkZSB0byB0aGUgZW50aXR5LCBpZiBhbnksIGFuZCAKICAgICAqIGxvY2sgaXQgd2l0aCByZXNwZWN0IHRvIGdpdmVuIGxvY2sgbW9kZSB0eXBlLgogICAgICogPHA+SWYgdGhlIGxvY2sgbW9kZSB0eXBlIGlzIHBlc3NpbWlzdGljIGFuZCB0aGUgZW50aXR5IGluc3RhbmNlCiAgICAgKiBpcyBmb3VuZCBidXQgY2Fubm90IGJlIGxvY2tlZDoKICAgICAqIDx1bD4KICAgICAqIDxsaT4gdGhlIDxjb2RlPlBlc3NpbWlzdGljTG9ja0V4Y2VwdGlvbjwvY29kZT4gd2lsbCBiZSB0aHJvd24gaWYgdGhlIGRhdGFiYXNlCiAgICAgKiAgICBsb2NraW5nIGZhaWx1cmUgY2F1c2VzIHRyYW5zYWN0aW9uLWxldmVsIHJvbGxiYWNrCiAgICAgKiA8bGk+IHRoZSA8Y29kZT5Mb2NrVGltZW91dEV4Y2VwdGlvbjwvY29kZT4gd2lsbCBiZSB0aHJvd24gaWYgdGhlCiAgICAgKiAgICBkYXRhYmFzZSBsb2NraW5nIGZhaWx1cmUgY2F1c2VzIG9ubHkgc3RhdGVtZW50LWxldmVsIAogICAgICogICAgcm9sbGJhY2suCiAgICAgKiA8L3VsPgogICAgICogQHBhcmFtIGVudGl0eSAgZW50aXR5IGluc3RhbmNlCiAgICAgKiBAcGFyYW0gbG9ja01vZGUgIGxvY2sgbW9kZQogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGluc3RhbmNlIGlzIG5vdAogICAgICogICAgICAgICBhbiBlbnRpdHkgb3IgdGhlIGVudGl0eSBpcyBub3QgbWFuYWdlZAogICAgICogQHRocm93cyBUcmFuc2FjdGlvblJlcXVpcmVkRXhjZXB0aW9uIGlmIGludm9rZWQgb24gYSAKICAgICAqICAgICAgICAgY29udGFpbmVyLW1hbmFnZWQgZW50aXR5IG1hbmFnZXIgb2YgdHlwZQogICAgICogICAgICAgICA8Y29kZT5QZXJzaXN0ZW5jZUNvbnRleHRUeXBlLlRSQU5TQUNUSU9OPC9jb2RlPiB3aGVuIHRoZXJlIGlzCiAgICAgKiAgICAgICAgIG5vIHRyYW5zYWN0aW9uOyBpZiBpbnZva2VkIG9uIGFuIGV4dGVuZGVkIGVudGl0eSBtYW5hZ2VyIHdoZW4KICAgICAqICAgICAgICAgdGhlcmUgaXMgbm8gdHJhbnNhY3Rpb24gYW5kIGEgbG9jayBtb2RlIG90aGVyIHRoYW4gPGNvZGU+Tk9ORTwvY29kZT4KICAgICAqICAgICAgICAgaGFzIGJlZW4gc3BlY2lmaWVkOyBvciBpZiBpbnZva2VkIG9uIGFuIGV4dGVuZGVkIGVudGl0eSBtYW5hZ2VyCiAgICAgKiAgICAgICAgIHRoYXQgaGFzIG5vdCBiZWVuIGpvaW5lZCB0byB0aGUgY3VycmVudCB0cmFuc2FjdGlvbiBhbmQgYQogICAgICogICAgICAgICBsb2NrIG1vZGUgb3RoZXIgdGhhbiA8Y29kZT5OT05FPC9jb2RlPiBoYXMgYmVlbiBzcGVjaWZpZWQKICAgICAqIEB0aHJvd3MgRW50aXR5Tm90Rm91bmRFeGNlcHRpb24gaWYgdGhlIGVudGl0eSBubyBsb25nZXIgZXhpc3RzCiAgICAgKiAgICAgICAgIGluIHRoZSBkYXRhYmFzZQogICAgICogQHRocm93cyBQZXNzaW1pc3RpY0xvY2tFeGNlcHRpb24gaWYgcGVzc2ltaXN0aWMgbG9ja2luZyBmYWlscwogICAgICogICAgICAgICBhbmQgdGhlIHRyYW5zYWN0aW9uIGlzIHJvbGxlZCBiYWNrCiAgICAgKiBAdGhyb3dzIExvY2tUaW1lb3V0RXhjZXB0aW9uIGlmIHBlc3NpbWlzdGljIGxvY2tpbmcgZmFpbHMgYW5kCiAgICAgKiAgICAgICAgIG9ubHkgdGhlIHN0YXRlbWVudCBpcyByb2xsZWQgYmFjawogICAgICogQHRocm93cyBQZXJzaXN0ZW5jZUV4Y2VwdGlvbiBpZiBhbiB1bnN1cHBvcnRlZCBsb2NrIGNhbGwKICAgICAqICAgICAgICAgaXMgbWFkZQogICAgICogQHNpbmNlIEphdmEgUGVyc2lzdGVuY2UgMi4wCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHJlZnJlc2goT2JqZWN0IGVudGl0eSwgTG9ja01vZGVUeXBlIGxvY2tNb2RlKTsKCiAgICAvKioKICAgICAqIFJlZnJlc2ggdGhlIHN0YXRlIG9mIHRoZSBpbnN0YW5jZSBmcm9tIHRoZSBkYXRhYmFzZSwgCiAgICAgKiBvdmVyd3JpdGluZyBjaGFuZ2VzIG1hZGUgdG8gdGhlIGVudGl0eSwgaWYgYW55LCBhbmQgCiAgICAgKiBsb2NrIGl0IHdpdGggcmVzcGVjdCB0byBnaXZlbiBsb2NrIG1vZGUgdHlwZSBhbmQgd2l0aAogICAgICogc3BlY2lmaWVkIHByb3BlcnRpZXMuCiAgICAgKiA8cD5JZiB0aGUgbG9jayBtb2RlIHR5cGUgaXMgcGVzc2ltaXN0aWMgYW5kIHRoZSBlbnRpdHkgaW5zdGFuY2UKICAgICAqIGlzIGZvdW5kIGJ1dCBjYW5ub3QgYmUgbG9ja2VkOgogICAgICogPHVsPgogICAgICogPGxpPiB0aGUgPGNvZGU+UGVzc2ltaXN0aWNMb2NrRXhjZXB0aW9uPC9jb2RlPiB3aWxsIGJlIHRocm93biBpZiB0aGUgZGF0YWJhc2UKICAgICAqICAgIGxvY2tpbmcgZmFpbHVyZSBjYXVzZXMgdHJhbnNhY3Rpb24tbGV2ZWwgcm9sbGJhY2sKICAgICAqIDxsaT4gdGhlIDxjb2RlPkxvY2tUaW1lb3V0RXhjZXB0aW9uPC9jb2RlPiB3aWxsIGJlIHRocm93biBpZiB0aGUgZGF0YWJhc2UKICAgICAqICAgIGxvY2tpbmcgZmFpbHVyZSBjYXVzZXMgb25seSBzdGF0ZW1lbnQtbGV2ZWwgcm9sbGJhY2sKICAgICAqIDwvdWw+CiAgICAgKiA8cD5JZiBhIHZlbmRvci1zcGVjaWZpYyBwcm9wZXJ0eSBvciBoaW50IGlzIG5vdCByZWNvZ25pemVkLCAKICAgICAqICAgIGl0IGlzIHNpbGVudGx5IGlnbm9yZWQuICAKICAgICAqIDxwPlBvcnRhYmxlIGFwcGxpY2F0aW9ucyBzaG91bGQgbm90IHJlbHkgb24gdGhlIHN0YW5kYXJkIHRpbWVvdXQKICAgICAqIGhpbnQuIERlcGVuZGluZyBvbiB0aGUgZGF0YWJhc2UgaW4gdXNlIGFuZCB0aGUgbG9ja2luZwogICAgICogbWVjaGFuaXNtcyB1c2VkIGJ5IHRoZSBwcm92aWRlciwgdGhlIGhpbnQgbWF5IG9yIG1heSBub3QKICAgICAqIGJlIG9ic2VydmVkLgogICAgICogQHBhcmFtIGVudGl0eSAgZW50aXR5IGluc3RhbmNlCiAgICAgKiBAcGFyYW0gbG9ja01vZGUgIGxvY2sgbW9kZQogICAgICogQHBhcmFtIHByb3BlcnRpZXMgIHN0YW5kYXJkIGFuZCB2ZW5kb3Itc3BlY2lmaWMgcHJvcGVydGllcwogICAgICogICAgICAgIGFuZCBoaW50cwogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGluc3RhbmNlIGlzIG5vdAogICAgICogICAgICAgICBhbiBlbnRpdHkgb3IgdGhlIGVudGl0eSBpcyBub3QgbWFuYWdlZAogICAgICogQHRocm93cyBUcmFuc2FjdGlvblJlcXVpcmVkRXhjZXB0aW9uIGlmIGludm9rZWQgb24gYSAKICAgICAqICAgICAgICAgY29udGFpbmVyLW1hbmFnZWQgZW50aXR5IG1hbmFnZXIgb2YgdHlwZQogICAgICogICAgICAgICA8Y29kZT5QZXJzaXN0ZW5jZUNvbnRleHRUeXBlLlRSQU5TQUNUSU9OPC9jb2RlPiB3aGVuIHRoZXJlIGlzCiAgICAgKiAgICAgICAgIG5vIHRyYW5zYWN0aW9uOyBpZiBpbnZva2VkIG9uIGFuIGV4dGVuZGVkIGVudGl0eSBtYW5hZ2VyIHdoZW4KICAgICAqICAgICAgICAgdGhlcmUgaXMgbm8gdHJhbnNhY3Rpb24gYW5kIGEgbG9jayBtb2RlIG90aGVyIHRoYW4gPGNvZGU+Tk9ORTwvY29kZT4KICAgICAqICAgICAgICAgaGFzIGJlZW4gc3BlY2lmaWVkOyBvciBpZiBpbnZva2VkIG9uIGFuIGV4dGVuZGVkIGVudGl0eSBtYW5hZ2VyCiAgICAgKiAgICAgICAgIHRoYXQgaGFzIG5vdCBiZWVuIGpvaW5lZCB0byB0aGUgY3VycmVudCB0cmFuc2FjdGlvbiBhbmQgYQogICAgICogICAgICAgICBsb2NrIG1vZGUgb3RoZXIgdGhhbiA8Y29kZT5OT05FPC9jb2RlPiBoYXMgYmVlbiBzcGVjaWZpZWQKICAgICAqIEB0aHJvd3MgRW50aXR5Tm90Rm91bmRFeGNlcHRpb24gaWYgdGhlIGVudGl0eSBubyBsb25nZXIgZXhpc3RzCiAgICAgKiAgICAgICAgIGluIHRoZSBkYXRhYmFzZQogICAgICogQHRocm93cyBQZXNzaW1pc3RpY0xvY2tFeGNlcHRpb24gaWYgcGVzc2ltaXN0aWMgbG9ja2luZyBmYWlscwogICAgICogICAgICAgICBhbmQgdGhlIHRyYW5zYWN0aW9uIGlzIHJvbGxlZCBiYWNrCiAgICAgKiBAdGhyb3dzIExvY2tUaW1lb3V0RXhjZXB0aW9uIGlmIHBlc3NpbWlzdGljIGxvY2tpbmcgZmFpbHMgYW5kCiAgICAgKiAgICAgICAgIG9ubHkgdGhlIHN0YXRlbWVudCBpcyByb2xsZWQgYmFjawogICAgICogQHRocm93cyBQZXJzaXN0ZW5jZUV4Y2VwdGlvbiBpZiBhbiB1bnN1cHBvcnRlZCBsb2NrIGNhbGwKICAgICAqICAgICAgICAgaXMgbWFkZQogICAgICogQHNpbmNlIEphdmEgUGVyc2lzdGVuY2UgMi4wCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHJlZnJlc2goT2JqZWN0IGVudGl0eSwgTG9ja01vZGVUeXBlIGxvY2tNb2RlLAogICAgICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBPYmplY3Q+IHByb3BlcnRpZXMpOwogICAgCiAgICAvKioKICAgICAqIENsZWFyIHRoZSBwZXJzaXN0ZW5jZSBjb250ZXh0LCBjYXVzaW5nIGFsbCBtYW5hZ2VkCiAgICAgKiBlbnRpdGllcyB0byBiZWNvbWUgZGV0YWNoZWQuIENoYW5nZXMgbWFkZSB0byBlbnRpdGllcyB0aGF0CiAgICAgKiBoYXZlIG5vdCBiZWVuIGZsdXNoZWQgdG8gdGhlIGRhdGFiYXNlIHdpbGwgbm90IGJlCiAgICAgKiBwZXJzaXN0ZWQuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGNsZWFyKCk7CgogICAgLyoqCiAgICAgKiBSZW1vdmUgdGhlIGdpdmVuIGVudGl0eSBmcm9tIHRoZSBwZXJzaXN0ZW5jZSBjb250ZXh0LCBjYXVzaW5nCiAgICAgKiBhIG1hbmFnZWQgZW50aXR5IHRvIGJlY29tZSBkZXRhY2hlZC4gIFVuZmx1c2hlZCBjaGFuZ2VzIG1hZGUgCiAgICAgKiB0byB0aGUgZW50aXR5IGlmIGFueSAoaW5jbHVkaW5nIHJlbW92YWwgb2YgdGhlIGVudGl0eSksIAogICAgICogd2lsbCBub3QgYmUgc3luY2hyb25pemVkIHRvIHRoZSBkYXRhYmFzZS4gIEVudGl0aWVzIHdoaWNoIAogICAgICogcHJldmlvdXNseSByZWZlcmVuY2VkIHRoZSBkZXRhY2hlZCBlbnRpdHkgd2lsbCBjb250aW51ZSB0bwogICAgICogcmVmZXJlbmNlIGl0LgogICAgICogQHBhcmFtIGVudGl0eSAgZW50aXR5IGluc3RhbmNlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgaW5zdGFuY2UgaXMgbm90IGFuIAogICAgICogICAgICAgICBlbnRpdHkgCiAgICAgKiBAc2luY2UgSmF2YSBQZXJzaXN0ZW5jZSAyLjAKICAgICAqLwogICAgcHVibGljIHZvaWQgZGV0YWNoKE9iamVjdCBlbnRpdHkpOyAKCiAgICAvKioKICAgICAqIENoZWNrIGlmIHRoZSBpbnN0YW5jZSBpcyBhIG1hbmFnZWQgZW50aXR5IGluc3RhbmNlIGJlbG9uZ2luZwogICAgICogdG8gdGhlIGN1cnJlbnQgcGVyc2lzdGVuY2UgY29udGV4dC4KICAgICAqIEBwYXJhbSBlbnRpdHkgIGVudGl0eSBpbnN0YW5jZQogICAgICogQHJldHVybiBib29sZWFuIGluZGljYXRpbmcgaWYgZW50aXR5IGlzIGluIHBlcnNpc3RlbmNlIGNvbnRleHQKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIG5vdCBhbiBlbnRpdHkKICAgICAqLyAgICAKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBlbnRpdHkpOwoKICAgIC8qKgogICAgICogR2V0IHRoZSBjdXJyZW50IGxvY2sgbW9kZSBmb3IgdGhlIGVudGl0eSBpbnN0YW5jZS4KICAgICAqIEBwYXJhbSBlbnRpdHkgIGVudGl0eSBpbnN0YW5jZQogICAgICogQHJldHVybiBsb2NrIG1vZGUKICAgICAqIEB0aHJvd3MgVHJhbnNhY3Rpb25SZXF1aXJlZEV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBubyAKICAgICAqICAgICAgICAgdHJhbnNhY3Rpb24gb3IgaWYgdGhlIGVudGl0eSBtYW5hZ2VyIGhhcyBub3QgYmVlbgogICAgICogICAgICAgICBqb2luZWQgdG8gdGhlIGN1cnJlbnQgdHJhbnNhY3Rpb24KICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBpbnN0YW5jZSBpcyBub3QgYQogICAgICogICAgICAgICBtYW5hZ2VkIGVudGl0eSBhbmQgYSB0cmFuc2FjdGlvbiBpcyBhY3RpdmUKICAgICAqIEBzaW5jZSBKYXZhIFBlcnNpc3RlbmNlIDIuMAogICAgICovCiAgICBwdWJsaWMgTG9ja01vZGVUeXBlIGdldExvY2tNb2RlKE9iamVjdCBlbnRpdHkpOwoKICAgIC8qKiAKICAgICAqIFNldCBhbiBlbnRpdHkgbWFuYWdlciBwcm9wZXJ0eSBvciBoaW50LiAKICAgICAqIElmIGEgdmVuZG9yLXNwZWNpZmljIHByb3BlcnR5IG9yIGhpbnQgaXMgbm90IHJlY29nbml6ZWQsIGl0IGlzCiAgICAgKiBzaWxlbnRseSBpZ25vcmVkLiAKICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUgbmFtZSBvZiBwcm9wZXJ0eSBvciBoaW50CiAgICAgKiBAcGFyYW0gdmFsdWUgIHZhbHVlIGZvciBwcm9wZXJ0eSBvciBoaW50CiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIAogICAgICogICAgICAgICBub3QgdmFsaWQgZm9yIHRoZSBpbXBsZW1lbnRhdGlvbiAKICAgICAqIEBzaW5jZSBKYXZhIFBlcnNpc3RlbmNlIDIuMAogICAgICovIAogICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5TmFtZSwgT2JqZWN0IHZhbHVlKTsKCiAgICAvKioKICAgICAqIEdldCB0aGUgcHJvcGVydGllcyBhbmQgaGludHMgYW5kIGFzc29jaWF0ZWQgdmFsdWVzIHRoYXQgYXJlIGluIGVmZmVjdCAKICAgICAqIGZvciB0aGUgZW50aXR5IG1hbmFnZXIuIENoYW5naW5nIHRoZSBjb250ZW50cyBvZiB0aGUgbWFwIGRvZXMgCiAgICAgKiBub3QgY2hhbmdlIHRoZSBjb25maWd1cmF0aW9uIGluIGVmZmVjdC4KICAgICAqIEByZXR1cm4gbWFwIG9mIHByb3BlcnRpZXMgYW5kIGhpbnRzIGluIGVmZmVjdCBmb3IgZW50aXR5IG1hbmFnZXIKICAgICAqIEBzaW5jZSBKYXZhIFBlcnNpc3RlbmNlIDIuMAogICAgICovCiAgICBwdWJsaWMgTWFwPFN0cmluZywgT2JqZWN0PiBnZXRQcm9wZXJ0aWVzKCk7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+UXVlcnk8L2NvZGU+IGZvciBleGVjdXRpbmcgYQogICAgICogSmF2YSBQZXJzaXN0ZW5jZSBxdWVyeSBsYW5ndWFnZSBzdGF0ZW1lbnQuCiAgICAgKiBAcGFyYW0gcWxTdHJpbmcgYSBKYXZhIFBlcnNpc3RlbmNlIHF1ZXJ5IHN0cmluZwogICAgICogQHJldHVybiB0aGUgbmV3IHF1ZXJ5IGluc3RhbmNlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgcXVlcnkgc3RyaW5nIGlzCiAgICAgKiAgICAgICAgIGZvdW5kIHRvIGJlIGludmFsaWQKICAgICAqLwogICAgcHVibGljIFF1ZXJ5IGNyZWF0ZVF1ZXJ5KFN0cmluZyBxbFN0cmluZyk7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+VHlwZWRRdWVyeTwvY29kZT4gZm9yIGV4ZWN1dGluZyBhCiAgICAgKiBjcml0ZXJpYSBxdWVyeS4KICAgICAqIEBwYXJhbSBjcml0ZXJpYVF1ZXJ5ICBhIGNyaXRlcmlhIHF1ZXJ5IG9iamVjdAogICAgICogQHJldHVybiB0aGUgbmV3IHF1ZXJ5IGluc3RhbmNlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgY3JpdGVyaWEgcXVlcnkgaXMKICAgICAqICAgICAgICAgZm91bmQgdG8gYmUgaW52YWxpZAogICAgICogQHNpbmNlIEphdmEgUGVyc2lzdGVuY2UgMi4wCiAgICAgKi8KICAgIHB1YmxpYyA8VD4gVHlwZWRRdWVyeTxUPiBjcmVhdGVRdWVyeShDcml0ZXJpYVF1ZXJ5PFQ+IGNyaXRlcmlhUXVlcnkpOyAKCiAgICAvKioKICAgICAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiA8Y29kZT5RdWVyeTwvY29kZT4gZm9yIGV4ZWN1dGluZyBhIGNyaXRlcmlhCiAgICAgKiB1cGRhdGUgcXVlcnkuCiAgICAgKiBAcGFyYW0gdXBkYXRlUXVlcnkgIGEgY3JpdGVyaWEgdXBkYXRlIHF1ZXJ5IG9iamVjdAogICAgICogQHJldHVybiB0aGUgbmV3IHF1ZXJ5IGluc3RhbmNlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgdXBkYXRlIHF1ZXJ5IGlzCiAgICAgKiAgICAgICAgIGZvdW5kIHRvIGJlIGludmFsaWQKICAgICAqIEBzaW5jZSBKYXZhIFBlcnNpc3RlbmNlIDIuMQogICAgICovCiAgICBwdWJsaWMgUXVlcnkgY3JlYXRlUXVlcnkoQ3JpdGVyaWFVcGRhdGUgdXBkYXRlUXVlcnkpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIDxjb2RlPlF1ZXJ5PC9jb2RlPiBmb3IgZXhlY3V0aW5nIGEgY3JpdGVyaWEKICAgICAqIGRlbGV0ZSBxdWVyeS4KICAgICAqIEBwYXJhbSBkZWxldGVRdWVyeSAgYSBjcml0ZXJpYSBkZWxldGUgcXVlcnkgb2JqZWN0CiAgICAgKiBAcmV0dXJuIHRoZSBuZXcgcXVlcnkgaW5zdGFuY2UKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBkZWxldGUgcXVlcnkgaXMKICAgICAqICAgICAgICAgZm91bmQgdG8gYmUgaW52YWxpZAogICAgICogQHNpbmNlIEphdmEgUGVyc2lzdGVuY2UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBRdWVyeSBjcmVhdGVRdWVyeShDcml0ZXJpYURlbGV0ZSBkZWxldGVRdWVyeSk7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+VHlwZWRRdWVyeTwvY29kZT4gZm9yIGV4ZWN1dGluZyBhCiAgICAgKiBKYXZhIFBlcnNpc3RlbmNlIHF1ZXJ5IGxhbmd1YWdlIHN0YXRlbWVudC4KICAgICAqIFRoZSBzZWxlY3QgbGlzdCBvZiB0aGUgcXVlcnkgbXVzdCBjb250YWluIG9ubHkgYSBzaW5nbGUKICAgICAqIGl0ZW0sIHdoaWNoIG11c3QgYmUgYXNzaWduYWJsZSB0byB0aGUgdHlwZSBzcGVjaWZpZWQgYnkKICAgICAqIHRoZSA8Y29kZT5yZXN1bHRDbGFzczwvY29kZT4gYXJndW1lbnQuCiAgICAgKiBAcGFyYW0gcWxTdHJpbmcgYSBKYXZhIFBlcnNpc3RlbmNlIHF1ZXJ5IHN0cmluZwogICAgICogQHBhcmFtIHJlc3VsdENsYXNzIHRoZSB0eXBlIG9mIHRoZSBxdWVyeSByZXN1bHQKICAgICAqIEByZXR1cm4gdGhlIG5ldyBxdWVyeSBpbnN0YW5jZQogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIHF1ZXJ5IHN0cmluZyBpcyBmb3VuZAogICAgICogICAgICAgICB0byBiZSBpbnZhbGlkIG9yIGlmIHRoZSBxdWVyeSByZXN1bHQgaXMgZm91bmQgdG8KICAgICAqICAgICAgICAgbm90IGJlIGFzc2lnbmFibGUgdG8gdGhlIHNwZWNpZmllZCB0eXBlCiAgICAgKiBAc2luY2UgSmF2YSBQZXJzaXN0ZW5jZSAyLjAKICAgICAqLwogICAgcHVibGljIDxUPiBUeXBlZFF1ZXJ5PFQ+IGNyZWF0ZVF1ZXJ5KFN0cmluZyBxbFN0cmluZywgQ2xhc3M8VD4gcmVzdWx0Q2xhc3MpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIDxjb2RlPlF1ZXJ5PC9jb2RlPiBmb3IgZXhlY3V0aW5nIGEgbmFtZWQgcXVlcnkKICAgICAqIChpbiB0aGUgSmF2YSBQZXJzaXN0ZW5jZSBxdWVyeSBsYW5ndWFnZSBvciBpbiBuYXRpdmUgU1FMKS4KICAgICAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIGEgcXVlcnkgZGVmaW5lZCBpbiBtZXRhZGF0YQogICAgICogQHJldHVybiB0aGUgbmV3IHF1ZXJ5IGluc3RhbmNlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBhIHF1ZXJ5IGhhcyBub3QgYmVlbgogICAgICogICAgICAgICBkZWZpbmVkIHdpdGggdGhlIGdpdmVuIG5hbWUgb3IgaWYgdGhlIHF1ZXJ5IHN0cmluZyBpcwogICAgICogICAgICAgICBmb3VuZCB0byBiZSBpbnZhbGlkCiAgICAgKi8KICAgIHB1YmxpYyBRdWVyeSBjcmVhdGVOYW1lZFF1ZXJ5KFN0cmluZyBuYW1lKTsKCiAgICAvKioKICAgICAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiA8Y29kZT5UeXBlZFF1ZXJ5PC9jb2RlPiBmb3IgZXhlY3V0aW5nIGEKICAgICAqIEphdmEgUGVyc2lzdGVuY2UgcXVlcnkgbGFuZ3VhZ2UgbmFtZWQgcXVlcnkuCiAgICAgKiBUaGUgc2VsZWN0IGxpc3Qgb2YgdGhlIHF1ZXJ5IG11c3QgY29udGFpbiBvbmx5IGEgc2luZ2xlCiAgICAgKiBpdGVtLCB3aGljaCBtdXN0IGJlIGFzc2lnbmFibGUgdG8gdGhlIHR5cGUgc3BlY2lmaWVkIGJ5CiAgICAgKiB0aGUgPGNvZGU+cmVzdWx0Q2xhc3M8L2NvZGU+IGFyZ3VtZW50LgogICAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgb2YgYSBxdWVyeSBkZWZpbmVkIGluIG1ldGFkYXRhCiAgICAgKiBAcGFyYW0gcmVzdWx0Q2xhc3MgdGhlIHR5cGUgb2YgdGhlIHF1ZXJ5IHJlc3VsdAogICAgICogQHJldHVybiB0aGUgbmV3IHF1ZXJ5IGluc3RhbmNlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBhIHF1ZXJ5IGhhcyBub3QgYmVlbgogICAgICogICAgICAgICBkZWZpbmVkIHdpdGggdGhlIGdpdmVuIG5hbWUgb3IgaWYgdGhlIHF1ZXJ5IHN0cmluZyBpcwogICAgICogICAgICAgICBmb3VuZCB0byBiZSBpbnZhbGlkIG9yIGlmIHRoZSBxdWVyeSByZXN1bHQgaXMgZm91bmQgdG8KICAgICAqICAgICAgICAgbm90IGJlIGFzc2lnbmFibGUgdG8gdGhlIHNwZWNpZmllZCB0eXBlCiAgICAgKiBAc2luY2UgSmF2YSBQZXJzaXN0ZW5jZSAyLjAKICAgICAqLwogICAgcHVibGljIDxUPiBUeXBlZFF1ZXJ5PFQ+IGNyZWF0ZU5hbWVkUXVlcnkoU3RyaW5nIG5hbWUsIENsYXNzPFQ+IHJlc3VsdENsYXNzKTsKCiAgICAvKioKICAgICAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiA8Y29kZT5RdWVyeTwvY29kZT4gZm9yIGV4ZWN1dGluZwogICAgICogYSBuYXRpdmUgU1FMIHN0YXRlbWVudCwgZS5nLiwgZm9yIHVwZGF0ZSBvciBkZWxldGUuCiAgICAgKiBJZiB0aGUgcXVlcnkgaXMgbm90IGFuIHVwZGF0ZSBvciBkZWxldGUgcXVlcnksIHF1ZXJ5CiAgICAgKiBleGVjdXRpb24gd2lsbCByZXN1bHQgaW4gZWFjaCByb3cgb2YgdGhlIFNRTCByZXN1bHQKICAgICAqIGJlaW5nIHJldHVybmVkIGFzIGEgcmVzdWx0IG9mIHR5cGUgT2JqZWN0W10gKG9yIGEgcmVzdWx0CiAgICAgKiBvZiB0eXBlIE9iamVjdCBpZiB0aGVyZSBpcyBvbmx5IG9uZSBjb2x1bW4gaW4gdGhlIHNlbGVjdAogICAgICogbGlzdC4pICBDb2x1bW4gdmFsdWVzIGFyZSByZXR1cm5lZCBpbiB0aGUgb3JkZXIgb2YgdGhlaXIKICAgICAqIGFwcGVhcmFuY2UgaW4gdGhlIHNlbGVjdCBsaXN0IGFuZCBkZWZhdWx0IEpEQkMgdHlwZQogICAgICogbWFwcGluZ3MgYXJlIGFwcGxpZWQuCiAgICAgKiBAcGFyYW0gc3FsU3RyaW5nIGEgbmF0aXZlIFNRTCBxdWVyeSBzdHJpbmcKICAgICAqIEByZXR1cm4gdGhlIG5ldyBxdWVyeSBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgUXVlcnkgY3JlYXRlTmF0aXZlUXVlcnkoU3RyaW5nIHNxbFN0cmluZyk7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+UXVlcnk8L2NvZGU+IGZvciBleGVjdXRpbmcKICAgICAqIGEgbmF0aXZlIFNRTCBxdWVyeS4KICAgICAqIEBwYXJhbSBzcWxTdHJpbmcgYSBuYXRpdmUgU1FMIHF1ZXJ5IHN0cmluZwogICAgICogQHBhcmFtIHJlc3VsdENsYXNzIHRoZSBjbGFzcyBvZiB0aGUgcmVzdWx0aW5nIGluc3RhbmNlKHMpCiAgICAgKiBAcmV0dXJuIHRoZSBuZXcgcXVlcnkgaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIFF1ZXJ5IGNyZWF0ZU5hdGl2ZVF1ZXJ5KFN0cmluZyBzcWxTdHJpbmcsIENsYXNzIHJlc3VsdENsYXNzKTsKCiAgICAvKioKICAgICAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiA8Y29kZT5RdWVyeTwvY29kZT4gZm9yIGV4ZWN1dGluZwogICAgICogYSBuYXRpdmUgU1FMIHF1ZXJ5LgogICAgICogQHBhcmFtIHNxbFN0cmluZyBhIG5hdGl2ZSBTUUwgcXVlcnkgc3RyaW5nCiAgICAgKiBAcGFyYW0gcmVzdWx0U2V0TWFwcGluZyB0aGUgbmFtZSBvZiB0aGUgcmVzdWx0IHNldCBtYXBwaW5nCiAgICAgKiBAcmV0dXJuIHRoZSBuZXcgcXVlcnkgaW5zdGFuY2UKICAgICAqLwogICAgcHVibGljIFF1ZXJ5IGNyZWF0ZU5hdGl2ZVF1ZXJ5KFN0cmluZyBzcWxTdHJpbmcsIFN0cmluZyByZXN1bHRTZXRNYXBwaW5nKTsKCiAgICAvKioKICAgICAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiA8Y29kZT5TdG9yZWRQcm9jZWR1cmVRdWVyeTwvY29kZT4gZm9yIGV4ZWN1dGluZyBhCiAgICAgKiBzdG9yZWQgcHJvY2VkdXJlIGluIHRoZSBkYXRhYmFzZS4KICAgICAqIDxwPlBhcmFtZXRlcnMgbXVzdCBiZSByZWdpc3RlcmVkIGJlZm9yZSB0aGUgc3RvcmVkIHByb2NlZHVyZSBjYW4KICAgICAqIGJlIGV4ZWN1dGVkLgogICAgICogPHA+SWYgdGhlIHN0b3JlZCBwcm9jZWR1cmUgcmV0dXJucyBvbmUgb3IgbW9yZSByZXN1bHQgc2V0cywKICAgICAqIGFueSByZXN1bHQgc2V0IHdpbGwgYmUgcmV0dXJuZWQgYXMgYSBsaXN0IG9mIHR5cGUgT2JqZWN0W10uCiAgICAgKiBAcGFyYW0gbmFtZSBuYW1lIGFzc2lnbmVkIHRvIHRoZSBzdG9yZWQgcHJvY2VkdXJlIHF1ZXJ5CiAgICAgKiBpbiBtZXRhZGF0YQogICAgICogQHJldHVybiB0aGUgbmV3IHN0b3JlZCBwcm9jZWR1cmUgcXVlcnkgaW5zdGFuY2UKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGEgcXVlcnkgaGFzIG5vdCBiZWVuCiAgICAgKiBkZWZpbmVkIHdpdGggdGhlIGdpdmVuIG5hbWUKICAgICAqIEBzaW5jZSBKYXZhIFBlcnNpc3RlbmNlIDIuMQogICAgICovCiAgICBwdWJsaWMgU3RvcmVkUHJvY2VkdXJlUXVlcnkgY3JlYXRlTmFtZWRTdG9yZWRQcm9jZWR1cmVRdWVyeShTdHJpbmcgbmFtZSk7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+U3RvcmVkUHJvY2VkdXJlUXVlcnk8L2NvZGU+IGZvciBleGVjdXRpbmcgYQogICAgICogc3RvcmVkIHByb2NlZHVyZSBpbiB0aGUgZGF0YWJhc2UuCiAgICAgKiA8cD5QYXJhbWV0ZXJzIG11c3QgYmUgcmVnaXN0ZXJlZCBiZWZvcmUgdGhlIHN0b3JlZCBwcm9jZWR1cmUgY2FuCiAgICAgKiBiZSBleGVjdXRlZC4KICAgICAqIDxwPklmIHRoZSBzdG9yZWQgcHJvY2VkdXJlIHJldHVybnMgb25lIG9yIG1vcmUgcmVzdWx0IHNldHMsCiAgICAgKiBhbnkgcmVzdWx0IHNldCB3aWxsIGJlIHJldHVybmVkIGFzIGEgbGlzdCBvZiB0eXBlIE9iamVjdFtdLgogICAgICogQHBhcmFtIHByb2NlZHVyZU5hbWUgbmFtZSBvZiB0aGUgc3RvcmVkIHByb2NlZHVyZSBpbiB0aGUKICAgICAqIGRhdGFiYXNlCiAgICAgKiBAcmV0dXJuIHRoZSBuZXcgc3RvcmVkIHByb2NlZHVyZSBxdWVyeSBpbnN0YW5jZQogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgYSBzdG9yZWQgcHJvY2VkdXJlIG9mIHRoZQogICAgICogZ2l2ZW4gbmFtZSBkb2VzIG5vdCBleGlzdCAob3IgdGhlIHF1ZXJ5IGV4ZWN1dGlvbiB3aWxsCiAgICAgKiBmYWlsKQogICAgICogQHNpbmNlIEphdmEgUGVyc2lzdGVuY2UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBTdG9yZWRQcm9jZWR1cmVRdWVyeSBjcmVhdGVTdG9yZWRQcm9jZWR1cmVRdWVyeShTdHJpbmcgcHJvY2VkdXJlTmFtZSk7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+U3RvcmVkUHJvY2VkdXJlUXVlcnk8L2NvZGU+IGZvciBleGVjdXRpbmcgYQogICAgICogc3RvcmVkIHByb2NlZHVyZSBpbiB0aGUgZGF0YWJhc2UuCiAgICAgKiA8cD5QYXJhbWV0ZXJzIG11c3QgYmUgcmVnaXN0ZXJlZCBiZWZvcmUgdGhlIHN0b3JlZCBwcm9jZWR1cmUgY2FuCiAgICAgKiBiZSBleGVjdXRlZC4KICAgICAqIDxwPlRoZSA8Y29kZT5yZXN1bHRDbGFzczwvY29kZT4gYXJndW1lbnRzIG11c3QgYmUgc3BlY2lmaWVkIGluIHRoZSBvcmRlciBpbgogICAgICogd2hpY2ggdGhlIHJlc3VsdCBzZXRzIHdpbGwgYmUgcmV0dXJuZWQgYnkgdGhlIHN0b3JlZCBwcm9jZWR1cmUKICAgICAqIGludm9jYXRpb24uCiAgICAgKiBAcGFyYW0gcHJvY2VkdXJlTmFtZSBuYW1lIG9mIHRoZSBzdG9yZWQgcHJvY2VkdXJlIGluIHRoZQogICAgICogZGF0YWJhc2UKICAgICAqIEBwYXJhbSByZXN1bHRDbGFzc2VzIGNsYXNzZXMgdG8gd2hpY2ggdGhlIHJlc3VsdCBzZXRzCiAgICAgKiBwcm9kdWNlZCBieSB0aGUgc3RvcmVkIHByb2NlZHVyZSBhcmUgdG8KICAgICAqIGJlIG1hcHBlZAogICAgICogQHJldHVybiB0aGUgbmV3IHN0b3JlZCBwcm9jZWR1cmUgcXVlcnkgaW5zdGFuY2UKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGEgc3RvcmVkIHByb2NlZHVyZSBvZiB0aGUKICAgICAqIGdpdmVuIG5hbWUgZG9lcyBub3QgZXhpc3QgKG9yIHRoZSBxdWVyeSBleGVjdXRpb24gd2lsbAogICAgICogZmFpbCkKICAgICAqIEBzaW5jZSBKYXZhIFBlcnNpc3RlbmNlIDIuMQogICAgICovCiAgICBwdWJsaWMgU3RvcmVkUHJvY2VkdXJlUXVlcnkgY3JlYXRlU3RvcmVkUHJvY2VkdXJlUXVlcnkoCgkgICAgICAgU3RyaW5nIHByb2NlZHVyZU5hbWUsIENsYXNzLi4uIHJlc3VsdENsYXNzZXMpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIDxjb2RlPlN0b3JlZFByb2NlZHVyZVF1ZXJ5PC9jb2RlPiBmb3IgZXhlY3V0aW5nIGEKICAgICAqIHN0b3JlZCBwcm9jZWR1cmUgaW4gdGhlIGRhdGFiYXNlLgogICAgICogPHA+UGFyYW1ldGVycyBtdXN0IGJlIHJlZ2lzdGVyZWQgYmVmb3JlIHRoZSBzdG9yZWQgcHJvY2VkdXJlIGNhbgogICAgICogYmUgZXhlY3V0ZWQuCiAgICAgKiA8cD5UaGUgPGNvZGU+cmVzdWx0U2V0TWFwcGluZzwvY29kZT4gYXJndW1lbnRzIG11c3QgYmUgc3BlY2lmaWVkIGluIHRoZSBvcmRlcgogICAgICogaW4gd2hpY2ggdGhlIHJlc3VsdCBzZXRzIHdpbGwgYmUgcmV0dXJuZWQgYnkgdGhlIHN0b3JlZAogICAgICogcHJvY2VkdXJlIGludm9jYXRpb24uCiAgICAgKiBAcGFyYW0gcHJvY2VkdXJlTmFtZSBuYW1lIG9mIHRoZSBzdG9yZWQgcHJvY2VkdXJlIGluIHRoZQogICAgICogICAgICAgIGRhdGFiYXNlCiAgICAgKiBAcGFyYW0gcmVzdWx0U2V0TWFwcGluZ3MgdGhlIG5hbWVzIG9mIHRoZSByZXN1bHQgc2V0IG1hcHBpbmdzCiAgICAgKiAgICAgICAgdG8gYmUgdXNlZCBpbiBtYXBwaW5nIHJlc3VsdCBzZXRzCiAgICAgKiAgICAgICAgcmV0dXJuZWQgYnkgdGhlIHN0b3JlZCBwcm9jZWR1cmUKICAgICAqIEByZXR1cm4gdGhlIG5ldyBzdG9yZWQgcHJvY2VkdXJlIHF1ZXJ5IGluc3RhbmNlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBhIHN0b3JlZCBwcm9jZWR1cmUgb3IKICAgICAqICAgICAgICAgcmVzdWx0IHNldCBtYXBwaW5nIG9mIHRoZSBnaXZlbiBuYW1lIGRvZXMgbm90IGV4aXN0CiAgICAgKiAgICAgICAgIChvciB0aGUgcXVlcnkgZXhlY3V0aW9uIHdpbGwgZmFpbCkKICAgICAqLwogICAgcHVibGljIFN0b3JlZFByb2NlZHVyZVF1ZXJ5IGNyZWF0ZVN0b3JlZFByb2NlZHVyZVF1ZXJ5KAogICAgICAgICAgICAgIFN0cmluZyBwcm9jZWR1cmVOYW1lLCBTdHJpbmcuLi4gcmVzdWx0U2V0TWFwcGluZ3MpOwoKICAgIC8qKgogICAgICogSW5kaWNhdGUgdG8gdGhlIGVudGl0eSBtYW5hZ2VyIHRoYXQgYSBKVEEgdHJhbnNhY3Rpb24gaXMKICAgICAqIGFjdGl2ZSBhbmQgam9pbiB0aGUgcGVyc2lzdGVuY2UgY29udGV4dCB0byBpdC4gCiAgICAgKiA8cD5UaGlzIG1ldGhvZCBzaG91bGQgYmUgY2FsbGVkIG9uIGEgSlRBIGFwcGxpY2F0aW9uIAogICAgICogbWFuYWdlZCBlbnRpdHkgbWFuYWdlciB0aGF0IHdhcyBjcmVhdGVkIG91dHNpZGUgdGhlIHNjb3BlCiAgICAgKiBvZiB0aGUgYWN0aXZlIHRyYW5zYWN0aW9uIG9yIG9uIGFuIGVudGl0eSBtYW5hZ2VyIG9mIHR5cGUKICAgICAqIDxjb2RlPlN5bmNocm9uaXphdGlvblR5cGUuVU5TWU5DSFJPTklaRUQ8L2NvZGU+IHRvIGFzc29jaWF0ZQogICAgICogaXQgd2l0aCB0aGUgY3VycmVudCBKVEEgdHJhbnNhY3Rpb24uCiAgICAgKiBAdGhyb3dzIFRyYW5zYWN0aW9uUmVxdWlyZWRFeGNlcHRpb24gaWYgdGhlcmUgaXMKICAgICAqICAgICAgICAgbm8gdHJhbnNhY3Rpb24KICAgICAqLwogICAgcHVibGljIHZvaWQgam9pblRyYW5zYWN0aW9uKCk7CgogICAgLyoqCiAgICAgKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZW50aXR5IG1hbmFnZXIgaXMgam9pbmVkIHRvIHRoZQogICAgICogY3VycmVudCB0cmFuc2FjdGlvbi4gUmV0dXJucyBmYWxzZSBpZiB0aGUgZW50aXR5IG1hbmFnZXIKICAgICAqIGlzIG5vdCBqb2luZWQgdG8gdGhlIGN1cnJlbnQgdHJhbnNhY3Rpb24gb3IgaWYgbm8KICAgICAqIHRyYW5zYWN0aW9uIGlzIGFjdGl2ZQogICAgICogQHJldHVybiBib29sZWFuCiAgICAgKiBAc2luY2UgSmF2YSBQZXJzaXN0ZW5jZSAyLjEKICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNKb2luZWRUb1RyYW5zYWN0aW9uKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gYW4gb2JqZWN0IG9mIHRoZSBzcGVjaWZpZWQgdHlwZSB0byBhbGxvdyBhY2Nlc3MgdG8gdGhlCiAgICAgKiBwcm92aWRlci1zcGVjaWZpYyBBUEkuICAgSWYgdGhlIHByb3ZpZGVyJ3MgPGNvZGU+RW50aXR5TWFuYWdlcjwvY29kZT4KICAgICAqIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgdGhlIHNwZWNpZmllZCBjbGFzcywgdGhlCiAgICAgKiA8Y29kZT5QZXJzaXN0ZW5jZUV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLgogICAgICogQHBhcmFtIGNscyAgdGhlIGNsYXNzIG9mIHRoZSBvYmplY3QgdG8gYmUgcmV0dXJuZWQuICBUaGlzIGlzCiAgICAgKiBub3JtYWxseSBlaXRoZXIgdGhlIHVuZGVybHlpbmcgPGNvZGU+RW50aXR5TWFuYWdlcjwvY29kZT4gaW1wbGVtZW50YXRpb24KICAgICAqIGNsYXNzIG9yIGFuIGludGVyZmFjZSB0aGF0IGl0IGltcGxlbWVudHMuCiAgICAgKiBAcmV0dXJuIGFuIGluc3RhbmNlIG9mIHRoZSBzcGVjaWZpZWQgY2xhc3MKICAgICAqIEB0aHJvd3MgUGVyc2lzdGVuY2VFeGNlcHRpb24gaWYgdGhlIHByb3ZpZGVyIGRvZXMgbm90IAogICAgICogICAgICAgICBzdXBwb3J0IHRoZSBjYWxsIAogICAgICogQHNpbmNlIEphdmEgUGVyc2lzdGVuY2UgMi4wCiAgICAgKi8KICAgIHB1YmxpYyA8VD4gVCB1bndyYXAoQ2xhc3M8VD4gY2xzKTsgCgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIHVuZGVybHlpbmcgcHJvdmlkZXIgb2JqZWN0IGZvciB0aGUgPGNvZGU+RW50aXR5TWFuYWdlcjwvY29kZT4sCiAgICAgKiBpZiBhdmFpbGFibGUuIFRoZSByZXN1bHQgb2YgdGhpcyBtZXRob2QgaXMgaW1wbGVtZW50YXRpb24KICAgICAqIHNwZWNpZmljLiAKICAgICAqIDxwPlRoZSA8Y29kZT51bndyYXA8L2NvZGU+IG1ldGhvZCBpcyB0byBiZSBwcmVmZXJyZWQgZm9yIG5ldyBhcHBsaWNhdGlvbnMuCiAgICAgKiBAcmV0dXJuIHVuZGVybHlpbmcgcHJvdmlkZXIgb2JqZWN0IGZvciBFbnRpdHlNYW5hZ2VyCiAgICAgKi8KICAgIHB1YmxpYyBPYmplY3QgZ2V0RGVsZWdhdGUoKTsKCiAgICAvKioKICAgICAqIENsb3NlIGFuIGFwcGxpY2F0aW9uLW1hbmFnZWQgZW50aXR5IG1hbmFnZXIuIAogICAgICogQWZ0ZXIgdGhlIGNsb3NlIG1ldGhvZCBoYXMgYmVlbiBpbnZva2VkLCBhbGwgbWV0aG9kcwogICAgICogb24gdGhlIDxjb2RlPkVudGl0eU1hbmFnZXI8L2NvZGU+IGluc3RhbmNlIGFuZCBhbnkgCiAgICAgKiA8Y29kZT5RdWVyeTwvY29kZT4gYW5kIDxjb2RlPlR5cGVkUXVlcnk8L2NvZGU+CiAgICAgKiBvYmplY3RzIG9idGFpbmVkIGZyb20gaXQgd2lsbCB0aHJvdyB0aGUgPGNvZGU+SWxsZWdhbFN0YXRlRXhjZXB0aW9uPC9jb2RlPgogICAgICogZXhjZXB0IGZvciA8Y29kZT5nZXRQcm9wZXJ0aWVzPC9jb2RlPiwgCiAgICAgKiA8Y29kZT5nZXRUcmFuc2FjdGlvbjwvY29kZT4sIGFuZCA8Y29kZT5pc09wZW48L2NvZGU+ICh3aGljaCB3aWxsIHJldHVybiBmYWxzZSkuCiAgICAgKiBJZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiB0aGUgZW50aXR5IG1hbmFnZXIgaXMKICAgICAqIGpvaW5lZCB0byBhbiBhY3RpdmUgdHJhbnNhY3Rpb24sIHRoZSBwZXJzaXN0ZW5jZQogICAgICogY29udGV4dCByZW1haW5zIG1hbmFnZWQgdW50aWwgdGhlIHRyYW5zYWN0aW9uIGNvbXBsZXRlcy4gCiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgZW50aXR5IG1hbmFnZXIKICAgICAqICAgICAgICAgaXMgY29udGFpbmVyLW1hbmFnZWQKICAgICAqLwogICAgcHVibGljIHZvaWQgY2xvc2UoKTsKCiAgICAvKioKICAgICAqIERldGVybWluZSB3aGV0aGVyIHRoZSBlbnRpdHkgbWFuYWdlciBpcyBvcGVuLiAKICAgICAqIEByZXR1cm4gdHJ1ZSB1bnRpbCB0aGUgZW50aXR5IG1hbmFnZXIgaGFzIGJlZW4gY2xvc2VkCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzT3BlbigpOwoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSByZXNvdXJjZS1sZXZlbCA8Y29kZT5FbnRpdHlUcmFuc2FjdGlvbjwvY29kZT4gb2JqZWN0LiAKICAgICAqIFRoZSA8Y29kZT5FbnRpdHlUcmFuc2FjdGlvbjwvY29kZT4gaW5zdGFuY2UgbWF5IGJlIHVzZWQgc2VyaWFsbHkgdG8gCiAgICAgKiBiZWdpbiBhbmQgY29tbWl0IG11bHRpcGxlIHRyYW5zYWN0aW9ucy4KICAgICAqIEByZXR1cm4gRW50aXR5VHJhbnNhY3Rpb24gaW5zdGFuY2UKICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIGludm9rZWQgb24gYSBKVEEKICAgICAqICAgICAgICAgZW50aXR5IG1hbmFnZXIKICAgICAqLwogICAgcHVibGljIEVudGl0eVRyYW5zYWN0aW9uIGdldFRyYW5zYWN0aW9uKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGVudGl0eSBtYW5hZ2VyIGZhY3RvcnkgZm9yIHRoZSBlbnRpdHkgbWFuYWdlci4KICAgICAqIEByZXR1cm4gRW50aXR5TWFuYWdlckZhY3RvcnkgaW5zdGFuY2UKICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoZSBlbnRpdHkgbWFuYWdlciBoYXMgCiAgICAgKiAgICAgICAgIGJlZW4gY2xvc2VkCiAgICAgKiBAc2luY2UgSmF2YSBQZXJzaXN0ZW5jZSAyLjAKICAgICAqLwogICAgcHVibGljIEVudGl0eU1hbmFnZXJGYWN0b3J5IGdldEVudGl0eU1hbmFnZXJGYWN0b3J5KCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gYW4gaW5zdGFuY2Ugb2YgPGNvZGU+Q3JpdGVyaWFCdWlsZGVyPC9jb2RlPiBmb3IgdGhlIGNyZWF0aW9uIG9mCiAgICAgKiA8Y29kZT5Dcml0ZXJpYVF1ZXJ5PC9jb2RlPiBvYmplY3RzLgogICAgICogQHJldHVybiBDcml0ZXJpYUJ1aWxkZXIgaW5zdGFuY2UKICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoZSBlbnRpdHkgbWFuYWdlciBoYXMKICAgICAqICAgICAgICAgYmVlbiBjbG9zZWQKICAgICAqIEBzaW5jZSBKYXZhIFBlcnNpc3RlbmNlIDIuMAogICAgICovCiAgICBwdWJsaWMgQ3JpdGVyaWFCdWlsZGVyIGdldENyaXRlcmlhQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogUmV0dXJuIGFuIGluc3RhbmNlIG9mIDxjb2RlPk1ldGFtb2RlbDwvY29kZT4gaW50ZXJmYWNlIGZvciBhY2Nlc3MgdG8gdGhlCiAgICAgKiBtZXRhbW9kZWwgb2YgdGhlIHBlcnNpc3RlbmNlIHVuaXQuCiAgICAgKiBAcmV0dXJuIE1ldGFtb2RlbCBpbnN0YW5jZQogICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhlIGVudGl0eSBtYW5hZ2VyIGhhcwogICAgICogICAgICAgICBiZWVuIGNsb3NlZAogICAgICogQHNpbmNlIEphdmEgUGVyc2lzdGVuY2UgMi4wCiAgICAgKi8KICAgIHB1YmxpYyBNZXRhbW9kZWwgZ2V0TWV0YW1vZGVsKCk7Cn0K