PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEgVHJhbnNpdGlvbmFsLy9FTiI+CjxodG1sPgoKPGhlYWQ+CjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIKCWNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD13aW5kb3dzLTEyNTIiPgo8dGl0bGU+VW5kZXJzdGFuZGluZyBMYXlvdXRzIGluIFNXVDwvdGl0bGU+CjxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iLi4vYXJ0aWNsZS5jc3MiIHR5cGU9InRleHQvY3NzIiAvPgo8L2hlYWQ+Cjxib2R5Pgo8aDE+VW5kZXJzdGFuZGluZyBMYXlvdXRzIGluIFNXVDwvaDE+Cgo8ZGl2IGNsYXNzPSJzdW1tYXJ5Ij4KPGgyPlN1bW1hcnk8L2gyPgo8cD5XaGVuIHdyaXRpbmcgYXBwbGljYXRpb25zIGluIFNXVCwgeW91IG1heSBuZWVkIHRvIHVzZSA8aT5sYXlvdXRzPC9pPgp0byBnaXZlIHlvdXIgd2luZG93cyBhIHNwZWNpZmljIGxvb2suIEEgbGF5b3V0IGNvbnRyb2xzIHRoZSBwb3NpdGlvbiBhbmQKc2l6ZSBvZiBjaGlsZHJlbiBpbiBhIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4uIExheW91dCBjbGFzc2VzIGFyZQpzdWJjbGFzc2VzIG9mIHRoZSBhYnN0cmFjdCBjbGFzcyA8Y29kZT5MYXlvdXQ8L2NvZGU+LiBUaGlzIGFydGljbGUgc2hvd3MKeW91IGhvdyB0byB3b3JrIHdpdGggc3RhbmRhcmQgbGF5b3V0cywgYW5kIHdyaXRlIHlvdXIgb3duIGN1c3RvbSBsYXlvdXQKY2xhc3MuPC9wPgoKPGRpdiBjbGFzcz0iYXV0aG9yIj5CeSBDYXJvbHluIE1hY0xlb2QsIE9USTwvZGl2Pgo8ZGl2IGNsYXNzPSJjb3B5cmlnaHQiPkNvcHlyaWdodCAmY29weTsgMjAwMSwgMjAwMiBPYmplY3QKVGVjaG5vbG9neSBJbnRlcm5hdGlvbmFsLCBJbmMuPC9kaXY+CjxkaXYgY2xhc3M9ImRhdGUiPk1hcmNoIDIyLCAyMDAxPC9kaXY+Cgo8ZGl2IGNsYXNzPSJhdXRob3IiPlJldmlzZWQgYnkgU2hhbnRoYSBSYW1hY2hhbmRyYW4sIE9USTwvZGl2Pgo8ZGl2IGNsYXNzPSJkYXRlIj5NYXkgMDIsIDIwMDI8L2Rpdj4KCjxkaXYgY2xhc3M9ImF1dGhvciI+UmV2aXNlZCBieSBXYXluZSBCZWF0b24sIFRoZSBFY2xpcHNlCkZvdW5kYXRpb248L2Rpdj4KPGRpdiBjbGFzcz0iY29weXJpZ2h0Ij5Db3B5cmlnaHQgJmNvcHk7IDIwMDggVGhlIEVjbGlwc2UKRm91bmRhdGlvbiwgSW5jLjwvZGl2Pgo8ZGl2IGNsYXNzPSJkYXRlIj5NYXkgMzAsIDIwMDg8L2Rpdj4KPC9kaXY+Cgo8ZGl2IGNsYXNzPSJjb250ZW50Ij4KCjxoMj5PdmVydmlldzwvaDI+Cgo8cD5XaGVuIHdyaXRpbmcgYXBwbGljYXRpb25zIGluIHRoZSA8YQoJaHJlZj0iaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9zd3QiPlN0YW5kYXJkIFdpZGdldCBUb29sa2l0PC9hPiAoU1dUKSwKeW91IG1heSBuZWVkIHRvIHVzZSA8aT5sYXlvdXRzPC9pPiB0byBnaXZlIHlvdXIgd2luZG93cyBhIHNwZWNpZmljIGxvb2suCkEgbGF5b3V0IGNvbnRyb2xzIHRoZSBwb3NpdGlvbiBhbmQgc2l6ZSBvZiBjaGlsZHJlbiBpbiBhIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4uCkxheW91dCBjbGFzc2VzIGFyZSBzdWJjbGFzc2VzIG9mIHRoZSBhYnN0cmFjdCBjbGFzcyA8Y29kZT5MYXlvdXQ8L2NvZGU+LgpTV1QgcHJvdmlkZXMgc2V2ZXJhbCBzdGFuZGFyZCBsYXlvdXQgY2xhc3NlcywgYW5kIHlvdSBjYW4gd3JpdGUgY3VzdG9tCmxheW91dCBjbGFzc2VzLjwvcD4KCjxwPkluIFNXVCwgcG9zaXRpb25pbmcgYW5kIHNpemluZyBkb2VzIG5vdCBoYXBwZW4gYXV0b21hdGljYWxseS4KQXBwbGljYXRpb25zIGNhbiBkZWNpZGUgdG8gc2l6ZSBhbmQgcGxhY2UgYSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+J3MKY2hpbGRyZW4gaW5pdGlhbGx5LCBvciBpbiBhIHJlc2l6ZSBsaXN0ZW5lci4gQW5vdGhlciBvcHRpb24gaXMgdG8Kc3BlY2lmeSBhIGxheW91dCBjbGFzcyB0byBwb3NpdGlvbiBhbmQgc2l6ZSB0aGUgY2hpbGRyZW4uIElmIGNoaWxkcmVuCmFyZSBub3QgZ2l2ZW4gYSBzaXplLCB0aGV5IHdpbGwgaGF2ZSB6ZXJvIHNpemUgYW5kIHRoZXkgY2Fubm90IGJlIHNlZW4uPC9wPgoKPHA+VGhlIGRpYWdyYW0gYmVsb3cgaWxsdXN0cmF0ZXMgYSBmZXcgZ2VuZXJhbCB0ZXJtcyB0aGF0IGFyZSB1c2VkCndoZW4gZGlzY3Vzc2luZyBsYXlvdXRzLiBUaGUgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiAoaW4gdGhpcyBjYXNlLCBhIDxjb2RlPlRhYkZvbGRlcjwvY29kZT4pCmhhcyBhIDxpPmxvY2F0aW9uPC9pPiwgPGk+Y2xpZW50QXJlYTwvaT4gYW5kIDxpPnRyaW08L2k+LiBUaGUgc2l6ZSBvZgp0aGUgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiBpcyB0aGUgc2l6ZSBvZiB0aGUgPGk+Y2xpZW50QXJlYTwvaT4gcGx1cyB0aGUKc2l6ZSBvZiB0aGUgPGNvZGU+dHJpbTwvY29kZT4uIFRoaXMgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiBoYXMgdHdvCmNoaWxkcmVuIHRoYXQgYXJlIGxhaWQgb3V0IHNpZGUgYnkgc2lkZS4gQSA8Y29kZT5MYXlvdXQ8L2NvZGU+IGlzCm1hbmFnaW5nIHRoZSBzaXplIGFuZCBwb3NpdGlvbiBvZiB0aGUgY2hpbGRyZW4uIFRoaXMgPGNvZGU+TGF5b3V0PC9jb2RlPgphbGxvd3MgPGNvZGU+c3BhY2luZzwvY29kZT4gYmV0d2VlbiB0aGUgY2hpbGRyZW4sIGFuZCBhIDxpPm1hcmdpbjwvaT4KYmV0d2VlbiB0aGUgY2hpbGRyZW4gYW5kIHRoZSBlZGdlcyBvZiB0aGUgPGNvZGU+TGF5b3V0PC9jb2RlPi4gVGhlIHNpemUKb2YgdGhlIDxjb2RlPkxheW91dDwvY29kZT4gaXMgdGhlIHNhbWUgYXMgdGhlIHNpemUgb2YgdGhlIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4ncwo8aT5jbGllbnRBcmVhPC9pPi48L3A+Cgo8aW1nIHNyYz0iaW1hZ2VzL0dlbmVyYWxUZXJtcy5qcGciIC8+Cgo8cD5UaGUgPGk+cHJlZmVycmVkIHNpemU8L2k+IG9mIGEgd2lkZ2V0IGlzIHRoZSBtaW5pbXVtIHNpemUgbmVlZGVkCnRvIHNob3cgaXRzIGNvbnRlbnQuIEluIHRoZSBjYXNlIG9mIGEgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiwgdGhlCnByZWZlcnJlZCBzaXplIGlzIHRoZSBzbWFsbGVzdCByZWN0YW5nbGUgdGhhdCBjb250YWlucyBhbGwgb2YgaXRzCmNoaWxkcmVuLiBJZiBjaGlsZHJlbiBoYXZlIGJlZW4gcG9zaXRpb25lZCBieSB0aGUgYXBwbGljYXRpb24sIHRoZSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+CmNvbXB1dGVzIGl0cyBvd24gcHJlZmVycmVkIHNpemUgYmFzZWQgb24gdGhlIHNpemUgYW5kIHBvc2l0aW9uIG9mIHRoZQpjaGlsZHJlbi4gSWYgYSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IGlzIHVzaW5nIGEgbGF5b3V0IGNsYXNzIHRvCnBvc2l0aW9uIGl0cyBjaGlsZHJlbiwgaXQgYXNrcyB0aGUgPGNvZGU+TGF5b3V0PC9jb2RlPiB0byBjb21wdXRlIHRoZQpzaXplIG9mIGl0cyA8Y29kZT5jbGllbnRBcmVhPC9jb2RlPiwgYW5kIHRoZW4gaXQgYWRkcyBpbiB0aGUgPGNvZGU+dHJpbTwvY29kZT4KdG8gZGV0ZXJtaW5lIGl0cyBwcmVmZXJyZWQgc2l6ZS48L3A+Cgo8aDM+U3RhbmRhcmQgTGF5b3V0czwvaDM+Cgo8cD5UaGUgc3RhbmRhcmQgbGF5b3V0IGNsYXNzZXMgaW4gdGhlIFNXVCBsaWJyYXJ5IGFyZTo8L3A+Cgo8dWw+Cgk8bGk+PGNvZGU+RmlsbExheW91dDwvY29kZT4gbGF5cyBvdXQgZXF1YWwtc2l6ZWQgd2lkZ2V0cyBpbiBhCglzaW5nbGUgcm93IG9yIGNvbHVtbjwvbGk+Cgk8bGk+PGNvZGU+Um93TGF5b3V0PC9jb2RlPiBsYXlzIG91dCB3aWRnZXRzIGluIGEgcm93IG9yIHJvd3MsIHdpdGgKCWZpbGwsIHdyYXAsIGFuZCBzcGFjaW5nIG9wdGlvbnM8L2xpPgoJPGxpPjxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+IGxheXMgb3V0IHdpZGdldHMgaW4gYSBncmlkPC9saT4KCTxsaT48Y29kZT5Gb3JtTGF5b3V0PC9jb2RlPiBsYXlzIG91dCB3aWRnZXRzIGJ5IGNyZWF0aW5nCglhdHRhY2htZW50cyBmb3IgZWFjaCBvZiB0aGVpciBzaWRlczwvbGk+CjwvdWw+Cgo8cD5UbyB1c2UgdGhlIHN0YW5kYXJkIGxheW91dHMsIHlvdSBuZWVkIHRvIGltcG9ydCB0aGUgU1dUIGxheW91dApwYWNrYWdlOjwvcD4KCjxwcmU+aW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuKjs8L3ByZT4KCjxwPkxheW91dHMgYXJlIHBsdWdnYWJsZS4gVG8gc2V0IGEgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiB3aWRnZXQncwpsYXlvdXQsIHlvdSB1c2UgdGhlIHdpZGdldCdzIDxjb2RlPnNldExheW91dChMYXlvdXQpPC9jb2RlPiBtZXRob2QuIEluCnRoZSBmb2xsb3dpbmcgY29kZSwgYSA8Y29kZT5TaGVsbDwvY29kZT4gKGEgc3ViY2xhc3Mgb2YgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPikKaXMgdG9sZCB0byBwb3NpdGlvbiBpdHMgY2hpbGRyZW4gdXNpbmcgYSA8Y29kZT5Sb3dMYXlvdXQ8L2NvZGU+OjwvcD4KCjxwcmU+U2hlbGwgc2hlbGwgPSBuZXcgU2hlbGwoKTsNCnNoZWxsLnNldExheW91dChuZXcgUm93TGF5b3V0KCkpOzwvcHJlPgoKPHA+QSBsYXlvdXQgY2xhc3MgbWF5IGhhdmUgYSBjb3JyZXNwb25kaW5nIGxheW91dCBkYXRhIGNsYXNzOiBhCnN1YmNsYXNzIG9mIDxjb2RlPk9iamVjdDwvY29kZT4gdGhhdCBjb250YWlucyBsYXlvdXQgZGF0YSBmb3IgYSBzcGVjaWZpYwpjaGlsZC4gQnkgY29udmVudGlvbiwgbGF5b3V0IGRhdGEgY2xhc3NlcyBhcmUgaWRlbnRpZmllZCBieSBzdWJzdGl0dXRpbmcKJnF1b3Q7RGF0YSZxdW90OyBmb3IgJnF1b3Q7TGF5b3V0JnF1b3Q7IGluIHRoZSBjbGFzcyBuYW1lLiBGb3IgZXhhbXBsZSwKdGhlIHN0YW5kYXJkIGxheW91dCBjbGFzcyA8Y29kZT5Sb3dMYXlvdXQ8L2NvZGU+IGhhcyBhIGxheW91dCBkYXRhIGNsYXNzCmNhbGxlZCA8Y29kZT5Sb3dEYXRhPC9jb2RlPiwgdGhlIGxheW91dCBjbGFzcyA8Y29kZT5HcmlkTGF5b3V0PC9jb2RlPgp1c2VzIGEgbGF5b3V0IGRhdGEgY2xhc3MgY2FsbGVkIDxjb2RlPkdyaWREYXRhPC9jb2RlPiwgYW5kIHRoZSBsYXlvdXQKY2xhc3MgPGNvZGU+Rm9ybUxheW91dDwvY29kZT4gaGFzIGEgbGF5b3V0IGRhdGEgY2xhc3MgY2FsbGVkIDxjb2RlPkZvcm1EYXRhPC9jb2RlPi4KQSB3aWRnZXQncyBsYXlvdXQgZGF0YSBjbGFzcyBpcyBzZXQgYXMgZm9sbG93czo8L3A+Cgo8cHJlPkJ1dHRvbiBidXR0b24gPSBuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCk7DQpidXR0b24uc2V0TGF5b3V0RGF0YShuZXcgUm93RGF0YSg1MCwgNDApKTs8L3ByZT4KCjxoMz5FeGFtcGxlcyBpbiB0aGlzIERvY3VtZW50PC9oMz4KCjxwPk1vc3Qgb2YgdGhlIHNuYXBzaG90cyBpbiB0aGlzIGRvY3VtZW50IHdlcmUgdGFrZW4gYnkgcnVubmluZwp2YXJpYXRpb25zIG9uIHRoZSBmb2xsb3dpbmcgZXhhbXBsZSBjb2RlLiBXZSBtYXkgY2hhbmdlIHRoZSB0eXBlIG9mCmxheW91dCwgdGhlIG9wdGlvbnMgdXNlZCwgb3IgdGhlIHR5cGUgb3IgbnVtYmVyIG9mIGNoaWxkcmVuLjwvcD4KCjxwcmU+aW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LlJvd0xheW91dDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkJ1dHRvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkRpc3BsYXk7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5TaGVsbDsKCnB1YmxpYyBjbGFzcyBMYXlvdXRFeGFtcGxlIHsKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKICAgICAgICBEaXNwbGF5IGRpc3BsYXkgPSBuZXcgRGlzcGxheSgpOwogICAgICAgIFNoZWxsIHNoZWxsID0gbmV3IFNoZWxsKGRpc3BsYXkpOwogICAgICAgIC8vIENyZWF0ZSB0aGUgbGF5b3V0LgogICAgICAgIFJvd0xheW91dCBsYXlvdXQgPSBuZXcgUm93TGF5b3V0KCk7CiAgICAgICAgLy8gT3B0aW9uYWxseSBzZXQgbGF5b3V0IGZpZWxkcy4KICAgICAgICBsYXlvdXQud3JhcCA9IHRydWU7CiAgICAgICAgLy8gU2V0IHRoZSBsYXlvdXQgaW50byB0aGUgY29tcG9zaXRlLgogICAgICAgIHNoZWxsLnNldExheW91dChsYXlvdXQpOwogICAgICAgIC8vIENyZWF0ZSB0aGUgY2hpbGRyZW4gb2YgdGhlIGNvbXBvc2l0ZS4KICAgICAgICBuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCkuc2V0VGV4dCgiQjEiKTsKICAgICAgICBuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCkuc2V0VGV4dCgiV2lkZSBCdXR0b24gMiIpOwogICAgICAgIG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKS5zZXRUZXh0KCJCdXR0b24gMyIpOwogICAgICAgIHNoZWxsLnBhY2soKTsKICAgICAgICBzaGVsbC5vcGVuKCk7CiAgICAgICAgCiAgICAgICAgd2hpbGUgKCFzaGVsbC5pc0Rpc3Bvc2VkKCkpIHsKICAgICAgICAgICAgaWYgKCFkaXNwbGF5LnJlYWRBbmREaXNwYXRjaCgpKSBkaXNwbGF5LnNsZWVwKCk7CiAgICAgICAgfQogICAgfQp9PC9wcmU+Cgo8cD5SdW5uaW5nIHRoZSBhYm92ZSBjb2RlIHJlc3VsdHMgaW4gdGhlIGZvbGxvd2luZzo8L3A+Cgo8aW1nIHNyYz0iaW1hZ2VzL0xheW91dEV4YW1wbGUuanBnIiAvPgoKPHA+SWYgdGhlIHVzZXIgcmVzaXplcyB0aGUgc2hlbGwgc28gdGhhdCB0aGVyZSBpcyBubyBsb25nZXIgcm9vbSBmb3IKQnV0dG9uIDMgb24gdGhlIHJpZ2h0LCB0aGUgPGNvZGU+Um93TGF5b3V0PC9jb2RlPiB3cmFwcyBCdXR0b24gMyB0byB0aGUKbmV4dCByb3csIGFzIGZvbGxvd3M6PC9wPgoKPGltZyBzcmM9ImltYWdlcy9MYXlvdXRFeGFtcGxlUmVzaXplZC5qcGciIC8+Cgo8cD5Vc2luZyBsYXlvdXRzIGlzIGNsb3NlbHkgdGllZCB3aXRoIHJlc2l6ZSwgYXMgd2Ugc2hhbGwgc2VlLgpDb25zZXF1ZW50bHksIG1vc3Qgb2YgdGhlIGV4YW1wbGVzIGluIHRoaXMgZG9jdW1lbnQgc2hvdyB3aGF0IHdvdWxkCmhhcHBlbiBpZiB0aGUgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiBiZWNvbWVzIHNtYWxsZXIgb3IgbGFyZ2VyLCBpbiBvcmRlcgp0byBpbGx1c3RyYXRlIGhvdyB0aGUgPGNvZGU+TGF5b3V0PC9jb2RlPiB3b3Jrcy48L3A+Cgo8aDI+RmlsbExheW91dDwvaDI+Cgo8cD48Y29kZT5GaWxsTGF5b3V0PC9jb2RlPiBpcyB0aGUgc2ltcGxlc3QgbGF5b3V0IGNsYXNzLiBJdCBsYXlzIG91dAp3aWRnZXRzIGluIGEgc2luZ2xlIHJvdyBvciBjb2x1bW4sIGZvcmNpbmcgdGhlbSB0byBiZSB0aGUgc2FtZSBzaXplLgpJbml0aWFsbHksIHRoZSB3aWRnZXRzIHdpbGwgYWxsIGJlIGFzIHRhbGwgYXMgdGhlIHRhbGxlc3Qgd2lkZ2V0LCBhbmQgYXMKd2lkZSBhcyB0aGUgd2lkZXN0LiA8Y29kZT5GaWxsTGF5b3V0PC9jb2RlPiBkb2VzIG5vdCB3cmFwLCBhbmQgeW91CmNhbm5vdCBzcGVjaWZ5IG1hcmdpbnMgb3Igc3BhY2luZy4gWW91IG1pZ2h0IHVzZSBpdCB0byBsYXkgb3V0IGJ1dHRvbnMKaW4gYSB0YXNrIGJhciBvciB0b29sIGJhciwgb3IgdG8gc3RhY2sgY2hlY2tib3hlcyBpbiBhIDxjb2RlPkdyb3VwPC9jb2RlPi4KPGNvZGU+RmlsbExheW91dDwvY29kZT4gY2FuIGFsc28gYmUgdXNlZCB3aGVuIGEgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPgpvbmx5IGhhcyBvbmUgY2hpbGQuIEZvciBleGFtcGxlLCBpZiBhIDxjb2RlPlNoZWxsPC9jb2RlPiBoYXMgYSBzaW5nbGUgPGNvZGU+R3JvdXA8L2NvZGU+CmNoaWxkLCA8Y29kZT5GaWxsTGF5b3V0PC9jb2RlPiB3aWxsIGNhdXNlIHRoZSA8Y29kZT5Hcm91cDwvY29kZT4gdG8KY29tcGxldGVseSBmaWxsIHRoZSA8Y29kZT5TaGVsbDwvY29kZT4uPC9wPgoKPHA+SGVyZSBpcyB0aGUgcmVsZXZhbnQgcG9ydGlvbiBvZiB0aGUgZXhhbXBsZSBjb2RlLiBGaXJzdCB3ZSBjcmVhdGUKYSA8Y29kZT5GaWxsTGF5b3V0PC9jb2RlPiwgdGhlbiAoaWYgd2Ugd2FudCB2ZXJ0aWNhbCkgd2Ugc2V0IGl0cyA8Y29kZT50eXBlPC9jb2RlPgpmaWVsZCB0byA8Y29kZT5TV1QuVkVSVElDQUw8L2NvZGU+LCBhbmQgc2V0IGl0IGludG8gdGhlIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4KKGEgPGNvZGU+U2hlbGw8L2NvZGU+KS4gVGhlIDxjb2RlPlNoZWxsPC9jb2RlPiBoYXMgdGhyZWUgcHVzaCBidXR0b24KY2hpbGRyZW4sICZxdW90O0IxJnF1b3Q7LCAmcXVvdDtXaWRlIEJ1dHRvbiAyJnF1b3Q7LCBhbmQgJnF1b3Q7QnV0dG9uCjMmcXVvdDsuIE5vdGUgdGhhdCBpbiBhIDxjb2RlPkZpbGxMYXlvdXQ8L2NvZGU+LCBjaGlsZHJlbiBhcmUgYWx3YXlzIHRoZQpzYW1lIHNpemUsIGFuZCB0aGV5IGZpbGwgYWxsIGF2YWlsYWJsZSBzcGFjZS48L3A+Cgo8cHJlPkZpbGxMYXlvdXQgZmlsbExheW91dCA9IG5ldyBGaWxsTGF5b3V0KCk7DQpmaWxsTGF5b3V0LnR5cGUgPSBTV1QuVkVSVElDQUw7DQpzaGVsbC5zZXRMYXlvdXQoZmlsbExheW91dCk7DQpuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCkuc2V0VGV4dCgmcXVvdDtCMSZxdW90Oyk7DQpuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCkuc2V0VGV4dCgmcXVvdDtXaWRlIEJ1dHRvbiAyJnF1b3Q7KTsNCm5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKS5zZXRUZXh0KCZxdW90O0J1dHRvbiAzJnF1b3Q7KTs8L3ByZT4KCjxwPlRoZSBmb2xsb3dpbmcgdGFibGUgc2hvd3MgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gYSBob3Jpem9udGFsCmFuZCB2ZXJ0aWNhbCA8Y29kZT5GaWxsTGF5b3V0PC9jb2RlPiwgaW5pdGlhbGx5IGFuZCBhZnRlciB0aGUgcGFyZW50IGhhcwpncm93bi48L3A+Cgo8dGFibGU+Cgk8dHI+CgkJPHRkPiZuYnNwOzwvdGQ+CgkJPHRkPgoJCTxwPkluaXRpYWw8L3A+CgkJPC90ZD4KCQk8dGQ+CgkJPHA+QWZ0ZXIgcmVzaXplPC9wPgoJCTwvdGQ+Cgk8L3RyPgoJPHRyPgoJCTx0ZD48Y29kZT5maWxsTGF5b3V0LnR5cGUgPSBTV1QuSE9SSVpPTlRBTDwvY29kZT4KCQk8cD4oZGVmYXVsdCk8L3A+CgkJPC90ZD4KCQk8dGQ+PGltZyBzcmM9ImltYWdlcy9GaWxsTGF5b3V0U2FtcGxlSG9yaXpvbnRhbC5qcGciIC8+PC90ZD4KCQk8dGQ+PGltZyBzcmM9ImltYWdlcy9GaWxsTGF5b3V0U2FtcGxlSG9yaXpvbnRhbFJlc2l6ZWQuanBnIiAvPjwvdGQ+Cgk8L3RyPgoJPHRyPgoJCTx0ZD48Y29kZT5maWxsTGF5b3V0LnR5cGUgPSBTV1QuVkVSVElDQUw8L2NvZGU+PC90ZD4KCQk8dGQ+PGltZyBzcmM9ImltYWdlcy9GaWxsTGF5b3V0U2FtcGxlVmVydGljYWwuanBnIiAvPjwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvRmlsbExheW91dFNhbXBsZVZlcnRpY2FsUmVzaXplZC5qcGciIC8+PC90ZD4KCTwvdHI+CjwvdGFibGU+Cgo8aDI+Um93TGF5b3V0PC9oMj4KCjxwPjxjb2RlPlJvd0xheW91dDwvY29kZT4gaXMgbW9yZSBjb21tb25seSB1c2VkIHRoYW4gPGNvZGU+RmlsbExheW91dDwvY29kZT4KYmVjYXVzZSBvZiBpdHMgYWJpbGl0eSB0byB3cmFwLCBhbmQgYmVjYXVzZSBpdCBwcm92aWRlcyBjb25maWd1cmFibGUKbWFyZ2lucyBhbmQgc3BhY2luZy4gPGNvZGU+Um93TGF5b3V0PC9jb2RlPiBoYXMgYSBudW1iZXIgb2YKY29uZmlndXJhdGlvbiBmaWVsZHMuIEluIGFkZGl0aW9uLCB0aGUgaGVpZ2h0IGFuZCB3aWR0aCBvZiBlYWNoIHdpZGdldAppbiBhIDxjb2RlPlJvd0xheW91dDwvY29kZT4gY2FuIGJlIHNwZWNpZmllZCBieSBzZXR0aW5nIHRoZSB3aWRnZXQncyA8Y29kZT5Sb3dEYXRhPC9jb2RlPgpvYmplY3QgdXNpbmcgPGNvZGU+c2V0TGF5b3V0RGF0YTwvY29kZT4uPC9wPgoKPGgzPlJvd0xheW91dENvbmZpZ3VyYXRpb24gRmllbGRzPC9oMz4KCjxwPlRoZSA8Y29kZT50eXBlPC9jb2RlPiBmaWVsZCBjb250cm9scyB3aGV0aGVyIHRoZSA8Y29kZT5Sb3dMYXlvdXQ8L2NvZGU+CmxheXMgb3V0IHdpZGdldHMgaW4gaG9yaXpvbnRhbCByb3dzLCBvciB2ZXJ0aWNhbCBjb2x1bW5zLiA8Y29kZT5Sb3dMYXlvdXRzPC9jb2RlPgphcmUgaG9yaXpvbnRhbCBieSBkZWZhdWx0LjwvcD4KCjxwPlRoZSA8Y29kZT53cmFwPC9jb2RlPiBmaWVsZCBjb250cm9scyB3aGV0aGVyIG9yIG5vdCB0aGUgPGNvZGU+Um93TGF5b3V0PC9jb2RlPgp3aWxsIHdyYXAgd2lkZ2V0cyBpbnRvIHRoZSBuZXh0IHJvdyBpZiB0aGVyZSBpc24ndCBlbm91Z2ggc3BhY2UgaW4gdGhlCmN1cnJlbnQgcm93LiA8Y29kZT5Sb3dMYXlvdXRzPC9jb2RlPiB3cmFwIGJ5IGRlZmF1bHQuPC9wPgoKPHA+SWYgdGhlIDxjb2RlPnBhY2s8L2NvZGU+IGZpZWxkIGlzIHRydWUsIHdpZGdldHMgaW4gYSA8Y29kZT5Sb3dMYXlvdXQ8L2NvZGU+CndpbGwgdGFrZSB0aGVpciBuYXR1cmFsIHNpemUgKCZxdW90O25hdHVyYWwgc2l6ZSZxdW90OyB2YXJpZXMgYnkgd2lkZ2V0Owp0aGUgbmF0dXJhbCBzaXplIGZvciBhIGxhYmVsIG9yIHB1c2ggYnV0dG9uLCBmb3IgZXhhbXBsZSwgaXMgbGFyZ2UgZW5vdWdoIHRvCmRpc3BsYXkgaXRzIHRleHR1YWwgY29udGVudHMpLCBhbmQgdGhleSB3aWxsIGJlIGFsaWduZWQgYXMgZmFyIHRvIHRoZQpsZWZ0IGFzIHBvc3NpYmxlLiBJZiBwYWNrIGlzIGZhbHNlLCB3aWRnZXRzIHdpbGwgZmlsbCB0aGUgYXZhaWxhYmxlCnNwYWNlLCBzaW1pbGFyIHRvIHRoZSB3aWRnZXRzIGluIGEgPGNvZGU+RmlsbExheW91dDwvY29kZT4uIDxjb2RlPlJvd0xheW91dHM8L2NvZGU+CnBhY2sgYnkgZGVmYXVsdC48L3A+Cgo8cD5JZiB0aGUgPGNvZGU+anVzdGlmeTwvY29kZT4gZmllbGQgaXMgdHJ1ZSwgd2lkZ2V0cyBpbiBhIDxjb2RlPlJvd0xheW91dDwvY29kZT4KYXJlIHNwcmVhZCBhY3Jvc3MgdGhlIGF2YWlsYWJsZSBzcGFjZSBmcm9tIGxlZnQgdG8gcmlnaHQuIElmIHRoZSBwYXJlbnQKPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiBncm93cyB3aWRlciwgdGhlIGV4dHJhIHNwYWNlIGlzIGRpc3RyaWJ1dGVkCmV2ZW5seSBhbW9uZyB0aGUgd2lkZ2V0cy4gSWYgYm90aCA8Y29kZT5wYWNrPC9jb2RlPiBhbmQgPGNvZGU+anVzdGlmeTwvY29kZT4KYXJlIHRydWUsIHdpZGdldHMgdGFrZSB0aGVpciBuYXR1cmFsIHNpemUsIGFuZCB0aGUgZXh0cmEgc3BhY2UgaXMgcGxhY2VkCmJldHdlZW4gdGhlIHdpZGdldHMgaW4gb3JkZXIgdG8ga2VlcCB0aGVtIGZ1bGx5IGp1c3RpZmllZC4gQnkgZGVmYXVsdCwgPGNvZGU+Um93TGF5b3V0czwvY29kZT4KZG8gbm90IGp1c3RpZnkuPC9wPgoKPHA+VGhlIDxjb2RlPm1hcmdpbkxlZnQ8L2NvZGU+LCA8Y29kZT5tYXJnaW5Ub3A8L2NvZGU+LCA8Y29kZT5tYXJnaW5SaWdodDwvY29kZT4sCjxjb2RlPm1hcmdpbkJvdHRvbTwvY29kZT4gYW5kIDxjb2RlPnNwYWNpbmc8L2NvZGU+IGZpZWxkcyBjb250cm9sIHRoZQpudW1iZXIgb2YgcGl4ZWxzIGJldHdlZW4gd2lkZ2V0cyAoPGNvZGU+c3BhY2luZzwvY29kZT4pIGFuZCB0aGUgbnVtYmVyCm9mIHBpeGVscyBiZXR3ZWVuIGEgd2lkZ2V0IGFuZCB0aGUgc2lkZSBvZiB0aGUgcGFyZW50IDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4KKG1hcmdpbikuIEJ5IGRlZmF1bHQsIDxjb2RlPlJvd0xheW91dHM8L2NvZGU+IGxlYXZlIDMgcGl4ZWxzIGZvciBtYXJnaW5zCmFuZCBzcGFjaW5nLiBUaGUgbWFyZ2luIGFuZCBzcGFjaW5nIGZpZWxkcyBhcmUgc2hvd24gaW4gdGhlIGZvbGxvd2luZwpkaWFncmFtLjwvcD4KCjxpbWcgc3JjPSJpbWFnZXMvUm93TGF5b3V0TWFyZ2lucy5qcGciIC8+Cgo8aDM+Um93TGF5b3V0IEV4YW1wbGVzPC9oMz4KCjxwPlRoZSBmb2xsb3dpbmcgZXhhbXBsZSBjb2RlIGNyZWF0ZXMgYSA8Y29kZT5Sb3dMYXlvdXQ8L2NvZGU+LCBzZXRzCmFsbCBvZiBpdHMgZmllbGRzIHRvIG5vbi1kZWZhdWx0IHZhbHVlcywgYW5kIHRoZW4gc2V0cyBpdCBpbnRvIGEgPGNvZGU+U2hlbGw8L2NvZGU+LjwvcD4KCjxwcmU+Um93TGF5b3V0IHJvd0xheW91dCA9IG5ldyBSb3dMYXlvdXQoKTsNCnJvd0xheW91dC53cmFwID0gZmFsc2U7DQpyb3dMYXlvdXQucGFjayA9IGZhbHNlOw0Kcm93TGF5b3V0Lmp1c3RpZnkgPSB0cnVlOw0Kcm93TGF5b3V0LnR5cGUgPSBTV1QuVkVSVElDQUw7DQpyb3dMYXlvdXQubWFyZ2luTGVmdCA9IDU7DQpyb3dMYXlvdXQubWFyZ2luVG9wID0gNTsNCnJvd0xheW91dC5tYXJnaW5SaWdodCA9IDU7DQpyb3dMYXlvdXQubWFyZ2luQm90dG9tID0gNTsNCnJvd0xheW91dC5zcGFjaW5nID0gMDsNCnNoZWxsLnNldExheW91dChyb3dMYXlvdXQpOzwvcHJlPgoKPHA+SWYgeW91IGFyZSB1c2luZyB0aGUgZGVmYXVsdCBmaWVsZCB2YWx1ZXMsIHlvdSBvbmx5IG5lZWQgb25lIGxpbmUKb2YgY29kZTo8L3A+Cgo8cHJlPnNoZWxsLnNldExheW91dChuZXcgUm93TGF5b3V0KCkpOzwvcHJlPgoKPHA+VGhlIHJlc3VsdHMgb2Ygc2V0dGluZyBzcGVjaWZpYyBmaWVsZHMgaXMgc2hvd24gYmVsb3c6PC9wPgoKPHRhYmxlPgoJPHRyPgoJCTx0ZCB3aWR0aD0iMTUwIj4mbmJzcDs8L3RkPgoJCTx0ZD4KCQk8cD5Jbml0aWFsPC9wPgoJCTwvdGQ+CgkJPHRkPgoJCTxwPkFmdGVyIHJlc2l6ZTwvcD4KCQk8L3RkPgoJPC90cj4KCTx0cj4KCQk8dGQ+PHByZT5yb3dMYXlvdXQud3JhcCA9IHRydWU7CnJvd0xheW91dC5wYWNrID0gdHJ1ZTsKcm93TGF5b3V0Lmp1c3RpZnkgPSBmYWxzZTsKcm93TGF5b3V0LnR5cGUgPSBTV1QuSE9SSVpPTlRBTDs8L3ByZT4KCQk8cD4oZGVmYXVsdHMpPC9wPgoJCTwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvUm93TGF5b3V0U2FtcGxlMDEuanBnIiAvPjwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvUm93TGF5b3V0U2FtcGxlMDFSZXNpemVkLmpwZyIgLz48cD5hbmQ8L3A+PGltZyBzcmM9ImltYWdlcy9Sb3dMYXlvdXRTYW1wbGUwMVJlc2l6ZWROYXJyb3dlci5qcGciIC8+PC90ZD4KCTwvdHI+Cgk8dHI+CgkJPHRkPjxwcmU+d3JhcCA9IGZhbHNlPC9wcmU+CgkJPHA+KGNsaXBzIGlmIG5vdCBlbm91Z2ggc3BhY2UpPC9wPgoJCTwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvUm93TGF5b3V0U2FtcGxlMDIuanBnIiAvPjwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvUm93TGF5b3V0U2FtcGxlMDJSZXNpemVkLmpwZyIgLz48L3RkPgoJPC90cj4KCTx0cj4KCQk8dGQ+PHByZT5wYWNrID0gZmFsc2U8L3ByZT4KCQk8cD4oYWxsIHdpZGdldHMgYXJlIHRoZSBzYW1lIHNpemUpPC9wPgoJCTwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvUm93TGF5b3V0U2FtcGxlMDMuanBnIiAvPjwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvUm93TGF5b3V0U2FtcGxlMDNSZXNpemVkLmpwZyIgLz48L3RkPgoJPC90cj4KCTx0cj4KCQk8dGQ+PHByZT5qdXN0aWZ5ID0gdHJ1ZTwvcHJlPgoJCTxwPih3aWRnZXRzIGFyZSBzcHJlYWQgYWNyb3NzIHRoZSBhdmFpbGFibGUgc3BhY2UpPC9wPgoJCTwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvUm93TGF5b3V0U2FtcGxlMDQuanBnIiAvPjwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvUm93TGF5b3V0U2FtcGxlMDRSZXNpemVkLmpwZyIgLz48L3RkPgoJPC90cj4KCTx0cj4KCQk8dGQ+PHByZT50eXBlID0gU1dULlZFUlRJQ0FMPC9wcmU+CgkJPHA+KHdpZGdldHMgYXJlIGFycmFuZ2VkIHZlcnRpY2FsbHkgaW4gY29sdW1ucyk8L3A+CgkJPC90ZD4KCQk8dGQ+PGltZyBzcmM9ImltYWdlcy9Sb3dMYXlvdXRTYW1wbGUwNS5qcGciIC8+PC90ZD4KCQk8dGQ+PGltZyBzcmM9ImltYWdlcy9Sb3dMYXlvdXRTYW1wbGUwNVJlc2l6ZWQuanBnIiAvPjwvdGQ+Cgk8L3RyPgo8L3RhYmxlPgoKPGgzPlVzaW5nIFJvd0RhdGEgT2JqZWN0cyB3aXRoIFJvd0xheW91dDwvaDM+Cgo8cD5FYWNoIHdpZGdldCBjb250cm9sbGVkIGJ5IGEgPGNvZGU+Um93TGF5b3V0PC9jb2RlPiBjYW4gaGF2ZSBpdHMKaW5pdGlhbCB3aWR0aCBhbmQgaGVpZ2h0IHNwZWNpZmllZCBieSBzZXR0aW5nIGl0cyA8Y29kZT5Sb3dEYXRhPC9jb2RlPgpvYmplY3QuIFRoZSBmb2xsb3dpbmcgY29kZSB1c2VzIDxjb2RlPlJvd0RhdGE8L2NvZGU+IG9iamVjdHMgdG8gY2hhbmdlCnRoZSBpbml0aWFsIHNpemUgb2YgdGhlIDxjb2RlPkJ1dHRvbnM8L2NvZGU+IGluIGEgPGNvZGU+U2hlbGw8L2NvZGU+LjwvcD4KCjxwcmU+aW1wb3J0IG9yZy5lY2xpcHNlLnN3dC4qOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLio7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC4qOw0KDQpwdWJsaWMgY2xhc3MgUm93RGF0YUV4YW1wbGUgew0KDQqgoCBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7DQqgoKCgoKAgRGlzcGxheSBkaXNwbGF5ID0gbmV3IERpc3BsYXkoKTsNCqCgoKCgoCBTaGVsbCBzaGVsbCA9IG5ldyBTaGVsbChkaXNwbGF5KTsNCqCgoKCgoCBzaGVsbC5zZXRMYXlvdXQobmV3IFJvd0xheW91dCgpKTsNCqCgoKCgoCBCdXR0b24gYnV0dG9uMSA9IG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKTsNCqCgoKCgoCBidXR0b24xLnNldFRleHQoJnF1b3Q7QnV0dG9uIDEmcXVvdDspOw0KoKCgoKCgIGJ1dHRvbjEuc2V0TGF5b3V0RGF0YShuZXcgUm93RGF0YSg1MCwgNDApKTsNCqCgoKCgoCBCdXR0b24gYnV0dG9uMiA9IG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKTsNCqCgoKCgoCBidXR0b24yLnNldFRleHQoJnF1b3Q7QnV0dG9uIDImcXVvdDspOw0KoKCgoKCgIGJ1dHRvbjIuc2V0TGF5b3V0RGF0YShuZXcgUm93RGF0YSg1MCwgMzApKTsNCqCgoKCgoCBCdXR0b24gYnV0dG9uMyA9IG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKTsNCqCgoKCgoCBidXR0b24zLnNldFRleHQoJnF1b3Q7QnV0dG9uIDMmcXVvdDspOw0KoKCgoKCgIGJ1dHRvbjMuc2V0TGF5b3V0RGF0YShuZXcgUm93RGF0YSg1MCwgMjApKTsNCqCgoKCgoCBzaGVsbC5wYWNrKCk7DQqgoKCgoKAgc2hlbGwub3BlbigpOwoNCqCgoKCgoCB3aGlsZSAoIXNoZWxsLmlzRGlzcG9zZWQoKSkgew0KoKCgoKCgoKCgIGlmICghZGlzcGxheS5yZWFkQW5kRGlzcGF0Y2goKSkgZGlzcGxheS5zbGVlcCgpOw0KoKCgoKCgIH0NCqCgIH0NCn08L3ByZT4KCjxwPkhlcmUgaXMgd2hhdCB5b3Ugc2VlIHdoZW4geW91IHJ1biB0aGlzIGNvZGUuPC9wPgoKPGltZyBzcmM9ImltYWdlcy9Sb3dEYXRhRXhhbXBsZS5qcGciIC8+Cgo8aDI+R3JpZExheW91dDwvaDI+Cgo8cD5XaXRoIGEgPGNvZGU+R3JpZExheW91dDwvY29kZT4sCnRoZSB3aWRnZXQgY2hpbGRyZW4gb2YgYSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IGFyZSBsYWlkIG91dCBpbiBhIGdyaWQuCjxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+IGhhcyBhIG51bWJlciBvZiBjb25maWd1cmF0aW9uIGZpZWxkcywgYW5kJm1kYXNoO2xpa2UKPGNvZGU+Um93TGF5b3V0PC9jb2RlPiZtZGFzaDt0aGUgd2lkZ2V0cyBpdCBsYXlzIG91dCBjYW4gaGF2ZSBhbiBhc3NvY2lhdGVkCmxheW91dCBkYXRhIG9iamVjdCwgY2FsbGVkIDxjb2RlPkdyaWREYXRhPC9jb2RlPi4gVGhlIHBvd2VyIG9mIDxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+CmxpZXMgaW4gdGhlIGFiaWxpdHkgdG8gY29uZmlndXJlIDxjb2RlPkdyaWREYXRhPC9jb2RlPiBmb3IgZWFjaCB3aWRnZXQKY29udHJvbGxlZCBieSB0aGUgPGNvZGU+R3JpZExheW91dDwvY29kZT4uPC9wPgoKPGgzPkdyaWRMYXlvdXQgQ29uZmlndXJhdGlvbiBGaWVsZHM8L2gzPgoKPHA+VGhlIDxjb2RlPm51bUNvbHVtbnM8L2NvZGU+IGZpZWxkIGlzIHRoZSBtb3N0IGltcG9ydGFudCBmaWVsZCBpbgphIDxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+LCBhbmQgaXQgaXMgdXN1YWxseSB0aGUgZmlyc3QgZmllbGQgYW4KYXBwbGljYXRpb24gd2lsbCBzZXQuIFdpZGdldHMgYXJlIGxhaWQgb3V0IGluIGNvbHVtbnMgZnJvbSBsZWZ0IHRvCnJpZ2h0LCBhbmQgYSBuZXcgcm93IGlzIGNyZWF0ZWQgd2hlbiA8Y29kZT5udW1Db2x1bW5zPC9jb2RlPiArIDEgd2lkZ2V0cwphcmUgYWRkZWQgdG8gdGhlIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4uIFRoZSBkZWZhdWx0IGlzIHRvIGhhdmUgb25seSAxCmNvbHVtbi4gVGhlIGZvbGxvd2luZyBjb2RlIGNyZWF0ZXMgYSA8Y29kZT5TaGVsbDwvY29kZT4gd2l0aCBmaXZlIDxjb2RlPkJ1dHRvbjwvY29kZT4KY2hpbGRyZW4gb2YgdmFyaW91cyB3aWR0aHMsIG1hbmFnZWQgYnkgYSA8Y29kZT5HcmlkTGF5b3V0PC9jb2RlPi4gVGhlCnRhYmxlIGJlbG93IHNob3dzIHRoZSBncmlkIHdoZW4gPGNvZGU+bnVtQ29sdW1uczwvY29kZT4gaXMgc2V0IHRvIG9uZSwgdHdvLApvciB0aHJlZS48L3A+Cgo8cHJlPkRpc3BsYXkgZGlzcGxheSA9IG5ldyBEaXNwbGF5KCk7DQpTaGVsbCBzaGVsbCA9IG5ldyBTaGVsbChkaXNwbGF5KTsNCkdyaWRMYXlvdXQgZ3JpZExheW91dCA9IG5ldyBHcmlkTGF5b3V0KCk7DQpncmlkTGF5b3V0Lm51bUNvbHVtbnMgPSAzOw0Kc2hlbGwuc2V0TGF5b3V0KGdyaWRMYXlvdXQpOw0KbmV3IEJ1dHRvbihzaGVsbCwgU1dULlBVU0gpLnNldFRleHQoJnF1b3Q7QjEmcXVvdDspOw0KbmV3IEJ1dHRvbihzaGVsbCwgU1dULlBVU0gpLnNldFRleHQoJnF1b3Q7V2lkZSBCdXR0b24gMiZxdW90Oyk7DQpuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCkuc2V0VGV4dCgmcXVvdDtCdXR0b24gMyZxdW90Oyk7DQpuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCkuc2V0VGV4dCgmcXVvdDtCNCZxdW90Oyk7DQpuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCkuc2V0VGV4dCgmcXVvdDtCdXR0b24gNSZxdW90Oyk7DQpzaGVsbC5wYWNrKCk7DQpzaGVsbC5vcGVuKCk7Cg0Kd2hpbGUgKCFzaGVsbC5pc0Rpc3Bvc2VkKCkpIHsNCglpZiAoIWRpc3BsYXkucmVhZEFuZERpc3BhdGNoKCkpIGRpc3BsYXkuc2xlZXAoKTsNCn08L3ByZT4KCjx0YWJsZT4KCTx0cj4KCQk8dGQ+PHByZT5udW1Db2x1bW5zID0gMTwvcHJlPjwvdGQ+CgkJPHRkPjxwcmU+bnVtQ29sdW1ucyA9IDI8L3ByZT48L3RkPgoJCTx0ZD48cHJlPm51bUNvbHVtbnMgPSAzPC9wcmU+PC90ZD4KCTwvdHI+Cgk8dHI+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvR3JpZExheW91dFNhbXBsZU51bUNvbHVtbnMxLmpwZyIgLz48L3RkPgoJCTx0ZD48aW1nIHNyYz0iaW1hZ2VzL0dyaWRMYXlvdXRTYW1wbGVOdW1Db2x1bW5zMi5qcGciIC8+PC90ZD4KCQk8dGQ+PGltZyBzcmM9ImltYWdlcy9HcmlkTGF5b3V0U2FtcGxlTnVtQ29sdW1uczMuanBnIiAvPjwvdGQ+Cgk8L3RyPgo8L3RhYmxlPgoKPHA+VGhlIDxjb2RlPm1ha2VDb2x1bW5zRXF1YWxXaWR0aDwvY29kZT4gZmllbGQgZm9yY2VzIHRoZSBjb2x1bW5zCnRvIGJlIHRoZSBzYW1lIHdpZHRoLiBUaGUgZGVmYXVsdCBpcyA8Y29kZT5mYWxzZTwvY29kZT4uIElmIHdlIGNoYW5nZSB0aGUgZXhhbXBsZQphYm92ZSB0byBoYXZlIHRocmVlIGNvbHVtbnMgb2YgZXF1YWwgd2lkdGgsIHRoaXMgaXMgd2hhdCB3ZSB3b3VsZCBnZXQgKG5vdGUKdGhhdCBpbiB0aGUgYWJzZW5jZSBvZiBmdXJ0aGVyIGluc3RydWN0aW9uLCB3aWRnZXRzIGFyZSBsZWZ0LWp1c3RpZmllZAppbiB0aGVpciBjb2x1bW5zKS48L3A+Cgo8aW1nIHNyYz0iaW1hZ2VzL0dyaWRMYXlvdXRTYW1wbGVFcXVhbFdpZHRoLmpwZyIgLz4KCjxwPlRoZSA8Y29kZT5tYXJnaW5XaWR0aDwvY29kZT4sIDxjb2RlPm1hcmdpbkhlaWdodDwvY29kZT4sIDxjb2RlPmhvcml6b250YWxTcGFjaW5nPC9jb2RlPiwKYW5kIDxjb2RlPnZlcnRpY2FsU3BhY2luZzwvY29kZT4gZmllbGRzIGluIGEgPGNvZGU+R3JpZExheW91dDwvY29kZT4gYXJlCnNpbWlsYXIgdG8gdGhvc2UgaW4gYSA8Y29kZT5Sb3dMYXlvdXQ8L2NvZGU+LiBUaGUgZGlmZmVyZW5jZSBpcyB0aGF0IHRoZQpsZWZ0IGFuZCByaWdodCBtYXJnaW5zIGFyZSBncm91cGVkIGludG8gPGNvZGU+bWFyZ2luV2lkdGg8L2NvZGU+LCBhbmQKdGhlIHRvcCBhbmQgYm90dG9tIG1hcmdpbnMgYXJlIGdyb3VwZWQgaW50byA8Y29kZT5tYXJnaW5IZWlnaHQ8L2NvZGU+LgpBbHNvLCBpbiBhIDxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+IHlvdSBjYW4gc3BlY2lmeSA8Y29kZT5ob3Jpem9udGFsU3BhY2luZzwvY29kZT4KYW5kIDxjb2RlPnZlcnRpY2FsU3BhY2luZzwvY29kZT4gaW5kZXBlbmRlbnRseSwgd2hlcmVhcyBpbiBhIDxjb2RlPlJvd0xheW91dDwvY29kZT4sCjxjb2RlPnNwYWNpbmc8L2NvZGU+IGFwcGxpZXMgdG8gaG9yaXpvbnRhbCBvciB2ZXJ0aWNhbCBkZXBlbmRpbmcgb24gdGhlCnR5cGUgb2YgdGhlIDxjb2RlPlJvd0xheW91dDwvY29kZT4uPC9wPgoKPGgzPkdyaWREYXRhIE9iamVjdCBGaWVsZHM8L2gzPgoKPHA+PGNvZGU+R3JpZERhdGE8L2NvZGU+IGlzIHRoZSBsYXlvdXQgZGF0YSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIDxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+LgpUbyBzZXQgYSB3aWRnZXQncyA8Y29kZT5HcmlkRGF0YTwvY29kZT4gb2JqZWN0LCB5b3UgdXNlIHRoZSA8Y29kZT5zZXRMYXlvdXREYXRhPC9jb2RlPgptZXRob2QuIEZvciBleGFtcGxlLCB0byBzZXQgdGhlIDxjb2RlPkdyaWREYXRhPC9jb2RlPiBmb3IgYSA8Y29kZT5CdXR0b248L2NvZGU+LAp3ZSBjb3VsZCBkbyB0aGUgZm9sbG93aW5nOjwvcD4KCjxwcmU+QnV0dG9uIGJ1dHRvbjEgPSBuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCk7DQpidXR0b24xLnNldFRleHQoIkIxIik7DQpidXR0b24xLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKCkpOzwvcHJlPgoKPHA+T2YgY291cnNlLCB0aGlzIGNvZGUganVzdCBjcmVhdGVzIGEgPGNvZGU+R3JpZERhdGE8L2NvZGU+IG9iamVjdAp3aXRoIGFsbCBvZiBpdHMgZmllbGRzIHNldCB0byB0aGVpciBkZWZhdWx0IHZhbHVlcywgd2hpY2ggaXMgdGhlIHNhbWUgYXMKbm90IHNldHRpbmcgdGhlIGxheW91dCBkYXRhIGF0IGFsbC4gVGhlcmUgYXJlIHR3byB3YXlzIHRvIGNyZWF0ZSBhIDxjb2RlPkdyaWREYXRhPC9jb2RlPgpvYmplY3Qgd2l0aCBjZXJ0YWluIGZpZWxkcyBzZXQuIFRoZSBmaXJzdCBpcyB0byBzZXQgdGhlIGZpZWxkcyBkaXJlY3RseTo8L3A+Cgo8cHJlPkdyaWREYXRhIGdyaWREYXRhID0gbmV3IEdyaWREYXRhKCk7DQpncmlkRGF0YS5ob3Jpem9udGFsQWxpZ25tZW50ID0gR3JpZERhdGEuRklMTDsNCmdyaWREYXRhLmdyYWJFeGNlc3NIb3Jpem9udGFsU3BhY2UgPSB0cnVlOw0KYnV0dG9uMS5zZXRMYXlvdXREYXRhKGdyaWREYXRhKTs8L3ByZT4gPGltZwoJc3JjPSJpbWFnZXMvR3JpZERhdGFTYW1wbGVIb3Jpem9udGFsRmlsbC5qcGciIC8+Cgo8cD5UaGUgc2Vjb25kIGlzIHRvIHRha2UgYWR2YW50YWdlIG9mIGNvbnZlbmllbmNlIEFQSTogc3R5bGUgYml0cwpkZWZpbmVkIGJ5IDxjb2RlPkdyaWREYXRhPC9jb2RlPjo8L3A+Cgo8cHJlPmJ1dHRvbjEuc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoR3JpZERhdGEuSE9SSVpPTlRBTF9BTElHTl9GSUxMIHwgR3JpZERhdGEuR1JBQl9IT1JJWk9OVEFMKSk7PC9wcmU+Cgo8cD5JbiBmYWN0LCBjZXJ0YWluIGNvbW1vbiBzdHlsZSBiaXQgY29tYmluYXRpb25zIGFyZSBwcm92aWRlZCBmb3IKZnVydGhlciBjb252ZW5pZW5jZTo8L3A+Cgo8cHJlPmJ1dHRvbjEuc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKSk7PC9wcmU+Cgo8cD5Ob3RlIHRoYXQgPGNvZGU+RklMTF88L2NvZGU+IGNvbnZlbmllbmNlIHN0eWxlcyBzZXQgYm90aCBmaWxsCmFsaWdubWVudCA8aT5hbmQ8L2k+IGdyYWIuIDxjb2RlPkdyaWREYXRhPC9jb2RlPiBzdHlsZSBiaXRzIGNhbiBvbmx5IGJlCnVzZWQgZm9yIGJvb2xlYW4gYW5kIGVudW1lcmF0aW9uIGZpZWxkcy4gTnVtZXJpYyBmaWVsZHMgbXVzdCBiZSBzZXQKZGlyZWN0bHkuPC9wPgoKPHA+T25lIGZpbmFsIG5vdGUgYWJvdXQgPGNvZGU+R3JpZERhdGE8L2NvZGU+IG9iamVjdHMgYmVmb3JlIHdlIGdldAppbnRvIHRoZWlyIGZpZWxkczogZG8gbm90IHJldXNlIDxjb2RlPkdyaWREYXRhPC9jb2RlPiBvYmplY3RzLiBFdmVyeQp3aWRnZXQgaW4gYSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IHRoYXQgaXMgbWFuYWdlZCBieSBhIDxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+Cm11c3QgaGF2ZSBhIHVuaXF1ZSA8Y29kZT5HcmlkRGF0YTwvY29kZT4gb2JqZWN0LiBJZiB0aGUgbGF5b3V0IGRhdGEgZm9yCmEgd2lkZ2V0IGluIGEgPGNvZGU+R3JpZExheW91dDwvY29kZT4gaXMgbnVsbCBhdCBsYXlvdXQgdGltZSwgYSB1bmlxdWUgPGNvZGU+R3JpZERhdGE8L2NvZGU+Cm9iamVjdCBpcyBjcmVhdGVkIGZvciBpdC48L3A+Cgo8cD5UaGUgPGNvZGU+aG9yaXpvbnRhbEFsaWdubWVudDwvY29kZT4gYW5kIDxjb2RlPnZlcnRpY2FsQWxpZ25tZW50PC9jb2RlPgpmaWVsZHMgc3BlY2lmeSB3aGVyZSB0byBwbGFjZSBhIHdpZGdldCBob3Jpem9udGFsbHkgYW5kL29yIHZlcnRpY2FsbHkKd2l0aGluIGl0cyBncmlkIGNlbGwuIEVhY2ggYWxpZ25tZW50IGZpZWxkIGNhbiBoYXZlIG9uZSBvZiB0aGUgZm9sbG93aW5nCnZhbHVlczo8L3A+Cgo8dWw+Cgk8bGk+PGNvZGU+QkVHSU5OSU5HPC9jb2RlPjwvbGk+Cgk8bGk+PGNvZGU+Q0VOVEVSPC9jb2RlPjwvbGk+Cgk8bGk+PGNvZGU+RU5EPC9jb2RlPjwvbGk+Cgk8bGk+PGNvZGU+RklMTDwvY29kZT48L2xpPgo8L3VsPgoKPHA+VGhlIGRlZmF1bHQgaG9yaXpvbnRhbEFsaWdubWVudCBpcyBCRUdJTk5JTkcgKG9yIGxlZnQtYWxpZ25lZCkuClRoZSBkZWZhdWx0IHZlcnRpY2FsQWxpZ25tZW50IGlzIENFTlRFUi48L3A+Cgo8cD5MZXQncyBnbyBiYWNrIHRvIG91ciBmaXZlLWJ1dHRvbiBleGFtcGxlIHdpdGggdGhyZWUgY29sdW1ucywgYW5kCndlIHdpbGwgdmFyeSB0aGUgPGNvZGU+aG9yaXpvbnRhbEFsaWdubWVudDwvY29kZT4gb2YgQnV0dG9uIDUuPC9wPgoKPHRhYmxlPgoJPHRyPgoJCTx0ZD48cHJlPmhvcml6b250YWxBbGlnbm1lbnQgPSBHcmlkRGF0YS5CRUdJTk5JTkc8L3ByZT4KCQk8cD4oZGVmYXVsdCk8L3A+CgkJPC90ZD4KCQk8dGQ+PGltZyBzcmM9ImltYWdlcy9HcmlkRGF0YVNhbXBsZUJlZ2lubmluZy5qcGciIC8+PC90ZD4KCTwvdHI+Cgk8dHI+CgkJPHRkPjxwcmU+aG9yaXpvbnRhbEFsaWdubWVudCA9IEdyaWREYXRhLkNFTlRFUjwvcHJlPjwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvR3JpZERhdGFTYW1wbGVDZW50ZXIuanBnIiAvPjwvdGQ+Cgk8L3RyPgoJPHRyPgoJCTx0ZD48cHJlPmhvcml6b250YWxBbGlnbm1lbnQgPSBHcmlkRGF0YS5FTkQ8L3ByZT48L3RkPgoJCTx0ZD48aW1nIHNyYz0iaW1hZ2VzL0dyaWREYXRhU2FtcGxlRW5kLmpwZyIgLz48L3RkPgoJPC90cj4KCTx0cj4KCQk8dGQ+PHByZT5ob3Jpem9udGFsQWxpZ25tZW50ID0gR3JpZERhdGEuRklMTDwvcHJlPjwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvR3JpZERhdGFTYW1wbGVGaWxsLmpwZyIgLz48L3RkPgoJPC90cj4KPC90YWJsZT4KCjxwPlRoZSA8Y29kZT5ob3Jpem9udGFsSW5kZW50PC9jb2RlPiBmaWVsZCBhbGxvd3MgeW91IHRvIG1vdmUgYQp3aWRnZXQgdG8gdGhlIHJpZ2h0IGJ5IGEgc3BlY2lmaWVkIG51bWJlciBvZiBwaXhlbHMuIFRoaXMgZmllbGQgaXMKdHlwaWNhbGx5IG9ubHkgdXNlZnVsIHdoZW4gdGhlIDxjb2RlPmhvcml6b250YWxBbGlnbm1lbnQ8L2NvZGU+IGlzIDxjb2RlPkJFR0lOTklORzwvY29kZT4uCldlIGNhbm5vdCB1c2UgYSBzdHlsZSBiaXQgdG8gc2V0IHRoZSBpbmRlbnQsIHNvIHdlIHdpbGwgaW5kZW50ICZxdW90O0J1dHRvbiA1JnF1b3Q7CmluIG91ciBleGFtcGxlIGJ5IGZvdXIgcGl4ZWxzIGFzIGZvbGxvd3M6PC9wPgoKPHByZT5HcmlkRGF0YSBncmlkRGF0YSA9IG5ldyBHcmlkRGF0YSgpOwpncmlkRGF0YS5ob3Jpem9udGFsSW5kZW50ID0gNDsKYnV0dG9uNS5zZXRMYXlvdXREYXRhKGdyaWREYXRhKTs8L3ByZT4gPGltZwoJc3JjPSJpbWFnZXMvR3JpZERhdGFTYW1wbGVJbmRlbnQuanBnIiAvPgoKPHA+VGhlIDxjb2RlPmhvcml6b250YWxTcGFuPC9jb2RlPiBhbmQgPGNvZGU+dmVydGljYWxTcGFuPC9jb2RlPgpmaWVsZHMgbGV0IHdpZGdldHMgb2NjdXB5IG1vcmUgdGhhbiBvbmUgZ3JpZCBjZWxsLiBUaGV5IGFyZSBvZnRlbiB1c2VkCmluIGNvbmp1bmN0aW9uIHdpdGggPGNvZGU+RklMTDwvY29kZT4gYWxpZ25tZW50LiBXZSBjYW4gbWFrZSAmcXVvdDtCdXR0b24gNSZxdW90OyBpbiBvdXIgZXhhbXBsZQpzcGFuIHRoZSBsYXN0IHR3byBjZWxscyBhcyBmb2xsb3dzOjwvcD4KCjxwcmU+R3JpZERhdGEgZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEoKTsKZ3JpZERhdGEuaG9yaXpvbnRhbEFsaWdubWVudCA9IEdyaWREYXRhLkZJTEw7CmdyaWREYXRhLmhvcml6b250YWxTcGFuID0gMjsKYnV0dG9uNS5zZXRMYXlvdXREYXRhKGdyaWREYXRhKTs8L3ByZT4gPGltZwoJc3JjPSJpbWFnZXMvR3JpZERhdGFTYW1wbGVTcGFuMDEuanBnIiAvPgoKPHA+SWYgd2UgZGVjaWRlIHRvIG1ha2UgJnF1b3Q7V2lkZSBCdXR0b24gMiZxdW90OyBzcGFuIHR3byBjZWxscyBpbnN0ZWFkLCB3ZQp3b3VsZCBlbmQgdXAgd2l0aCB0aGlzOjwvcD4KCjxwcmU+R3JpZERhdGEgZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEoKTsKZ3JpZERhdGEuaG9yaXpvbnRhbEFsaWdubWVudCA9IEdyaWREYXRhLkZJTEw7CmdyaWREYXRhLmhvcml6b250YWxTcGFuID0gMjsKYnV0dG9uMi5zZXRMYXlvdXREYXRhKGdyaWREYXRhKTs8L3ByZT4gPGltZwoJc3JjPSJpbWFnZXMvR3JpZERhdGFTYW1wbGVTcGFuMDIuanBnIiAvPgoKPHA+T3Igd2UgY291bGQgbWFrZSAmcXVvdDtCdXR0b24gMyZxdW90OyBzcGFuIHR3byBjZWxscyB2ZXJ0aWNhbGx5OjwvcD4KCjxwcmU+R3JpZERhdGEgZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEoKTsKZ3JpZERhdGEudmVydGljYWxBbGlnbm1lbnQgPSBHcmlkRGF0YS5GSUxMOwpncmlkRGF0YS52ZXJ0aWNhbFNwYW4gPSAyOwpidXR0b24zLnNldExheW91dERhdGEoZ3JpZERhdGEpOzwvcHJlPiA8aW1nCglzcmM9ImltYWdlcy9HcmlkRGF0YVNhbXBsZVNwYW4wMy5qcGciIC8+Cgo8cD5UaGUgPGNvZGU+Z3JhYkV4Y2Vzc0hvcml6b250YWxTcGFjZTwvY29kZT4gYW5kIDxjb2RlPmdyYWJFeGNlc3NWZXJ0aWNhbFNwYWNlPC9jb2RlPgpmaWVsZHMgYXJlIHR5cGljYWxseSB1c2VkIGZvciBsYXJnZXIgd2lkZ2V0cyBzdWNoIGFzIDxjb2RlPlRleHQsPC9jb2RlPgo8Y29kZT5MaXN0PC9jb2RlPiBvciA8Y29kZT5DYW52YXM8L2NvZGU+IHRvIGFsbG93IHRoZW0gdG8gZ3JvdyBpZiB0aGVpcgpjb250YWluaW5nIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4gZ3Jvd3MuIElmIGEgPGNvZGU+VGV4dDwvY29kZT4gaXMKZ3JhYmJpbmcgZXhjZXNzIGhvcml6b250YWwgc3BhY2UgYW5kIHRoZSB1c2VyIHJlc2l6ZXMgdGhlIDxjb2RlPlNoZWxsPC9jb2RlPgp3aWRlciwgdGhlbiB0aGUgPGNvZGU+VGV4dDwvY29kZT4gd2lsbCBnZXQgYWxsIG9mIHRoZSBuZXcgaG9yaXpvbnRhbApzcGFjZSBhbmQgb3RoZXIgd2lkZ2V0cyBpbiB0aGUgc2FtZSByb3cgd2lsbCBzdGF5IHRoZWlyIG9yaWdpbmFsIHdpZHRoLgpPZiBjb3Vyc2UsIHRoZSB3aWRnZXQgdGhhdCBpcyBncmFiYmluZyBleGNlc3Mgc3BhY2UgaXMgYWxzbyB0aGUgZmlyc3QKb25lIHRvIHNocmluayB3aGVuIHRoZSA8Y29kZT5TaGVsbDwvY29kZT4gZ2V0cyBzbWFsbGVyLiBJdCBpcyBlYXNpZXN0IHRvCmFsd2F5cyB0aGluayBvZiB0aGUgPGI+Z3JhYkV4Y2Vzc1NwYWNlPC9iPiBmaWVsZHMgaW4gdGhlIGNvbnRleHQgb2YKcmVzaXppbmcuIEZvciBhIHNpbXBsZSBleGFtcGxlLCBsZXQncyByZXVzZSB0aGUgcHJldmlvdXMgZXhhbXBsZSB3aGVyZQomcXVvdDtCdXR0b24gMyZxdW90OyBzcGFubmVkIHR3byBjZWxscyB2ZXJ0aWNhbGx5LiBIZXJlIGl0IGlzIGFnYWluOjwvcD4KCjxpbWcgc3JjPSJpbWFnZXMvR3JpZERhdGFTYW1wbGVTcGFuMDMuanBnIiAvPgoKPHA+SWYgd2UgcmVzaXplIHRoaXMgd2luZG93LCB0aGUgb25seSB0aGluZyB0aGF0IGhhcHBlbnMgaXMgdGhhdCB0aGUKd2luZG93IGdldHMgYmlnZ2VyOjwvcD4KCjxpbWcgc3JjPSJpbWFnZXMvR3JpZERhdGFTYW1wbGVTcGFuMDNSZXNpemVkLmpwZyIgLz4KCjxwPk5vdyB3ZSB3aWxsIHRlbGwgJnF1b3Q7QnV0dG9uIDMmcXVvdDsgdG8gZ3JhYiBleGNlc3MgaG9yaXpvbnRhbCBhbmQgdmVydGljYWwKc3BhY2UsIGFuZCAmcXVvdDtCMSZxdW90OyBhbmQgJnF1b3Q7QjQmcXVvdDsgdG8gZmlsbCB2ZXJ0aWNhbGx5ICh3aXRob3V0IGdyYWJiaW5nKSwgYW5kIHdlCnJlc2l6ZSB0aGUgd2luZG93IGFnYWluOjwvcD4KCjxwcmU+QnV0dG9uIGJ1dHRvbjEgPSBuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCk7CmJ1dHRvbjEuc2V0VGV4dCgmcXVvdDtCMSZxdW90Oyk7CkdyaWREYXRhIGdyaWREYXRhID0gbmV3IEdyaWREYXRhKCk7CmdyaWREYXRhLnZlcnRpY2FsQWxpZ25tZW50ID0gR3JpZERhdGEuRklMTDsKYnV0dG9uMS5zZXRMYXlvdXREYXRhKGdyaWREYXRhKTsKCm5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKS5zZXRUZXh0KCZxdW90O1dpZGUgQnV0dG9uIDImcXVvdDspOwoKQnV0dG9uIGJ1dHRvbjMgPSBuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCk7CmJ1dHRvbjMuc2V0VGV4dCgmcXVvdDtCdXR0b24gMyZxdW90Oyk7CmdyaWREYXRhID0gbmV3IEdyaWREYXRhKCk7CmdyaWREYXRhLnZlcnRpY2FsQWxpZ25tZW50ID0gR3JpZERhdGEuRklMTDsKZ3JpZERhdGEudmVydGljYWxTcGFuID0gMjsKZ3JpZERhdGEuZ3JhYkV4Y2Vzc1ZlcnRpY2FsU3BhY2UgPSB0cnVlOwpncmlkRGF0YS5ob3Jpem9udGFsQWxpZ25tZW50ID0gR3JpZERhdGEuRklMTDsKZ3JpZERhdGEuZ3JhYkV4Y2Vzc0hvcml6b250YWxTcGFjZSA9IHRydWU7CmJ1dHRvbjMuc2V0TGF5b3V0RGF0YShncmlkRGF0YSk7CgpCdXR0b24gYnV0dG9uNCA9IG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKTsKYnV0dG9uNC5zZXRUZXh0KCZxdW90O0I0JnF1b3Q7KTsKZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEoKTsKZ3JpZERhdGEudmVydGljYWxBbGlnbm1lbnQgPSBHcmlkRGF0YS5GSUxMOwpidXR0b240LnNldExheW91dERhdGEoZ3JpZERhdGEpOwoKbmV3IEJ1dHRvbihzaGVsbCwgU1dULlBVU0gpLnNldFRleHQoJnF1b3Q7QnV0dG9uIDUmcXVvdDspOzwvcHJlPiA8aW1nCglzcmM9ImltYWdlcy9HcmlkRGF0YVNhbXBsZUdyYWIwMS5qcGciIC8+Cgo8cD5UaGlzIHRpbWUsICZxdW90O0J1dHRvbiAzJnF1b3Q7IGdyZXcgaW4gYm90aCBkaXJlY3Rpb25zLCBhbmQgJnF1b3Q7QjQmcXVvdDsgZ3Jldwp2ZXJ0aWNhbGx5LiBUaGUgb3RoZXIgYnV0dG9ucyBzdGF5ZWQgdGhlaXIgb3JpZ2luYWwgc2l6ZXMuIEJlY2F1c2UKJnF1b3Q7QnV0dG9uIDMmcXVvdDsgd2FzIGdyYWJiaW5nIHZlcnRpY2FsbHkgYW5kIGl0IHNwYW5zIHR3byByb3dzLCB0aGUgPGk+bGFzdDwvaT4Kcm93IHRoYXQgaXQgc3BhbnMgZ3JldyB0YWxsZXIuIE5vdGUgdGhhdCAmcXVvdDtCMSZxdW90OyBkaWQgbm90Cmdyb3cmbWRhc2g7YWx0aG91Z2ggaXQgaXMgZmlsbGluZyB2ZXJ0aWNhbGx5Jm1kYXNoO2JlY2F1c2UgaXRzIHJvdyBkaWQKbm90IGdyb3cuIFNpbmNlICZxdW90O0J1dHRvbiAzJnF1b3Q7IHdhcyBncmFiYmluZyBob3Jpem9udGFsbHksIGl0cyBjb2x1bW4gZ3Jldwp3aWRlciwgYW5kIHNpbmNlIGl0IHdhcyBmaWxsaW5nIGhvcml6b250YWxseSwgaXQgZ3JldyB3aWRlciB0byBmaWxsIHRoZQpjb2x1bW4uPC9wPgoKPHA+SW4gYSB0eXBpY2FsIGFwcGxpY2F0aW9uIHdpbmRvdywgeW91IG9mdGVuIHdhbnQgdG8gaGF2ZSBhdCBsZWFzdApvbmUgd2lkZ2V0IHRoYXQgaXMgZ3JhYmJpbmcuIElmIG1vcmUgdGhhbiBvbmUgd2lkZ2V0IGlzIHRyeWluZyB0byBncmFiCnRoZSBzYW1lIHNwYWNlLCB0aGVuIHRoZSBleGNlc3Mgc3BhY2UgaXMgc2hhcmVkIGV2ZW5seSBhbW9uZyB0aGUKZ3JhYmJpbmcgd2lkZ2V0czo8L3A+Cgo8cHJlPmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkRGF0YTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuR3JpZExheW91dDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkRpc3BsYXk7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5MYWJlbDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkxpc3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5TaGVsbDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLlRleHQ7CgpwdWJsaWMgY2xhc3MgU2FtcGxlR3JhYkV4Y2VzcyB7CglwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CgkJRGlzcGxheSBkaXNwbGF5ID0gbmV3IERpc3BsYXkoKTsKCQlTaGVsbCBzaGVsbCA9IG5ldyBTaGVsbChkaXNwbGF5KTsKCQlzaGVsbC5zZXRMYXlvdXQobmV3IEdyaWRMYXlvdXQoMiwgZmFsc2UpKTsKCQkKCQlMYWJlbCBuYW1lTGFiZWwgPSBuZXcgTGFiZWwoc2hlbGwsIFNXVC5OT05FKTsKCQluYW1lTGFiZWwuc2V0VGV4dCgiTmFtZToiKTsKCQkKCQlUZXh0IG5hbWVUZXh0ID0gbmV3IFRleHQoc2hlbGwsIFNXVC5CT1JERVIpOwoJCUdyaWREYXRhIGdyaWREYXRhID0gbmV3IEdyaWREYXRhKCk7CgkJZ3JpZERhdGEuaG9yaXpvbnRhbEFsaWdubWVudCA9IFNXVC5GSUxMOwoJCWdyaWREYXRhLmdyYWJFeGNlc3NIb3Jpem9udGFsU3BhY2UgPSB0cnVlOwoJCW5hbWVUZXh0LnNldExheW91dERhdGEoZ3JpZERhdGEpOwoJCW5hbWVUZXh0LnNldFRleHQoIlRleHQgZ3Jvd3MgaG9yaXpvbnRhbGx5Iik7CgkJCgkJTGFiZWwgYWRkcmVzc0xhYmVsID0gbmV3IExhYmVsKHNoZWxsLCBTV1QuTk9ORSk7CgkJYWRkcmVzc0xhYmVsLnNldFRleHQoIkFkZHJlc3M6Iik7CgkJZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEoKTsKCQlncmlkRGF0YS52ZXJ0aWNhbEFsaWdubWVudCA9IFNXVC5UT1A7CgkJYWRkcmVzc0xhYmVsLnNldExheW91dERhdGEoZ3JpZERhdGEpOwoJCQoJCVRleHQgYWRkcmVzc1RleHQgPSBuZXcgVGV4dChzaGVsbCwgU1dULkJPUkRFUiB8IFNXVC5XUkFQIHwgU1dULk1VTFRJKTsKCQlncmlkRGF0YSA9IG5ldyBHcmlkRGF0YSgpOwoJCWdyaWREYXRhLmhvcml6b250YWxBbGlnbm1lbnQgPSBTV1QuRklMTDsKCQlncmlkRGF0YS5ncmFiRXhjZXNzSG9yaXpvbnRhbFNwYWNlID0gdHJ1ZTsKCQlncmlkRGF0YS52ZXJ0aWNhbEFsaWdubWVudCA9IFNXVC5GSUxMOwoJCWdyaWREYXRhLmdyYWJFeGNlc3NWZXJ0aWNhbFNwYWNlID0gdHJ1ZTsKCQlhZGRyZXNzVGV4dC5zZXRMYXlvdXREYXRhKGdyaWREYXRhKTsKCQlhZGRyZXNzVGV4dC5zZXRUZXh0KCJUaGlzIHRleHQgZmllbGQgYW5kIHRoZSBMaXN0XG5iZWxvdyBzaGFyZSBhbnkgZXhjZXNzIHNwYWNlLiIpOwoKCQlMYWJlbCBzcG9ydHNMYWJlbCA9IG5ldyBMYWJlbChzaGVsbCwgU1dULk5PTkUpOwoJCXNwb3J0c0xhYmVsLnNldFRleHQoIlNwb3J0cyBwbGF5ZWQ6Iik7CgkJZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEoKTsKCQlncmlkRGF0YS5ob3Jpem9udGFsU3BhbiA9IDI7CgkJc3BvcnRzTGFiZWwuc2V0TGF5b3V0RGF0YShncmlkRGF0YSk7CgkJCgkJTGlzdCBzcG9ydHNMaXN0ID0gbmV3IExpc3Qoc2hlbGwsIFNXVC5CT1JERVIgfCBTV1QuTVVMVEkpOwoJCWdyaWREYXRhID0gbmV3IEdyaWREYXRhKCk7CgkJZ3JpZERhdGEuaG9yaXpvbnRhbFNwYW4gPSAyOwoJCWdyaWREYXRhLmhvcml6b250YWxBbGlnbm1lbnQgPSBTV1QuRklMTDsKCQlncmlkRGF0YS5ncmFiRXhjZXNzSG9yaXpvbnRhbFNwYWNlID0gdHJ1ZTsKCQlncmlkRGF0YS52ZXJ0aWNhbEFsaWdubWVudCA9IFNXVC5GSUxMOwoJCWdyaWREYXRhLmdyYWJFeGNlc3NWZXJ0aWNhbFNwYWNlID0gdHJ1ZTsKCQlzcG9ydHNMaXN0LnNldExheW91dERhdGEoZ3JpZERhdGEpOwoJCXNwb3J0c0xpc3QuYWRkKCJIb2NrZXkiKTsKCQlzcG9ydHNMaXN0LmFkZCgiU3RyZWV0IEhvY2tleSIpOwoJCQkJCgkJc2hlbGwucGFjaygpOwoJCXNoZWxsLm9wZW4oKTsKCgkJd2hpbGUgKCFzaGVsbC5pc0Rpc3Bvc2VkKCkpIHsKCQkJaWYgKCFkaXNwbGF5LnJlYWRBbmREaXNwYXRjaCgpKQoJCQkJZGlzcGxheS5zbGVlcCgpOwoJCX0KCX0KfTwvcHJlPiA8aW1nIHNyYz0iaW1hZ2VzL0dyaWRMYXlvdXRHcmFiRXhjZXNzLmpwZyIgLz4goKCgoKAKPHA+V2hlbiByZXNpemVkLCB0aGUgc2luZ2xlIGxpbmUgKHRvcC1tb3N0KSA8Y29kZT5UZXh0PC9jb2RlPiBncm93cwp0byBjb25zdW1lIGFsbCBhdmFpbGFibGUgaG9yaXpvbnRhbCBzcGFjZSwgYW5kIHRoZSBzZWNvbmQgPGNvZGU+VGV4dDwvY29kZT4KYW5kIHRoZSA8Y29kZT5MaXN0PC9jb2RlPiBncm93IHRvIGNvbnN1bWUgYWxsIHJlbWFpbmluZyBzcGFjZSAoYm90aAp2ZXJ0aWNhbGx5IGFuZCBob3Jpem9udGFsbHkpOjwvcD4KCjxpbWcgc3JjPSJpbWFnZXMvR3JpZExheW91dEdyYWJFeGNlc3NSZXNpemVkLmpwZyIgLz4KCjxwPk9uZSBmaW5hbCBwb2ludCB0byBub3RlIGFib3V0IGdyYWJiaW5nOiBpZiBhIHdpZGdldCBpcyBzZXQgdG8KZ3JhYiBleGNlc3MgaG9yaXpvbnRhbCBzcGFjZSBhbmQgaXRzIHBhcmVudCA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IGdyb3dzCndpZGVyLCB0aGVuIHRoZSBlbnRpcmUgPGk+Y29sdW1uPC9pPiBjb250YWluaW5nIHRoYXQgd2lkZ2V0IGdyb3dzIHdpZGVyLgpJZiBhIHdpZGdldCBpcyBncmFiYmluZyBleGNlc3MgdmVydGljYWwgc3BhY2UgYW5kIGl0cyBwYXJlbnQgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPgpncm93cyB0YWxsZXIsIHRoZW4gdGhlIGVudGlyZSA8aT5yb3c8L2k+IGNvbnRhaW5pbmcgdGhhdCB3aWRnZXQgZ3Jvd3MKdGFsbGVyLiBUaGUgaW1wbGljYXRpb24gb2YgdGhpcyBpcyB0aGF0IGlmIGFueSBvdGhlciB3aWRnZXQgaW4gdGhlCmFmZmVjdGVkIGNvbHVtbiBvciByb3cgaGFzIDxpPmZpbGw8L2k+IGFsaWdubWVudCwgdGhlbiBpdCB3aWxsIHN0cmV0Y2gKYWxzby4gV2lkZ2V0cyB0aGF0IGhhdmUgYmVnaW5uaW5nLCBjZW50ZXIsIG9yIGVuZCBhbGlnbm1lbnQgd2lsbCBub3QKc3RyZXRjaDogdGhleSB3aWxsIHN0YXkgYXQgdGhlIGJlZ2lubmluZywgY2VudGVyIG9yIGVuZCBvZiB0aGUgd2lkZXIKY29sdW1uIG9yIHRhbGxlciByb3cuPC9wPgoKPHA+VGhlIDxjb2RlPndpZHRoSGludDwvY29kZT4gYW5kIDxjb2RlPmhlaWdodEhpbnQ8L2NvZGU+IGZpZWxkcwppbmRpY2F0ZSB0aGUgbnVtYmVyIG9mIHBpeGVscyB3aWRlIG9yIHRhbGwgdGhhdCB5b3Ugd291bGQgbGlrZSBhIHdpZGdldAp0byBiZSwgYXNzdW1pbmcgdGhhdCBpdCBkb2VzIG5vdCBjb25mbGljdCB3aXRoIG90aGVyIHJlcXVpcmVtZW50cyBpbiB0aGUKPGNvZGU+R3JpZExheW91dDwvY29kZT4ncyBjb25zdHJhaW50IHN5c3RlbS4gTG9va2luZyBiYWNrIGF0IHRoZQpmaXZlLWJ1dHRvbiwgdGhyZWUtY29sdW1uIGV4YW1wbGUsIHNheSB3ZSB3YW50ICZxdW90O0J1dHRvbiA1JnF1b3Q7IHRvIGJlIDcwIHBpeGVscwp3aWRlIGFuZCA0MCBwaXhlbHMgdGFsbC4gV2UgY29kZSBpdCBhcyBmb2xsb3dzOjwvcD4KCjxwcmU+R3JpZERhdGEgZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEoKTsNCmdyaWREYXRhLndpZHRoSGludCA9IDcwOw0KZ3JpZERhdGEuaGVpZ2h0SGludCA9IDQwOw0KYnV0dG9uNS5zZXRMYXlvdXREYXRhKGdyaWREYXRhKTs8L3ByZT4KCjxwPlRoZSBuYXR1cmFsIHNpemUgb2YgJnF1b3Q7QnV0dG9uIDUmcXVvdDsgaXMgc2hvd24gaW4gdGhlIHdpbmRvdyBvbiB0aGUgbGVmdCwKYmVsb3csIGFuZCB0aGUgNzAtcGl4ZWwgd2lkZSwgNDAtcGl4ZWwgdGFsbCAmcXVvdDtCdXR0b24gNSZxdW90OyBpcyBvbiB0aGUgcmlnaHQuPC9wPgoKPGltZyBzcmM9ImltYWdlcy9HcmlkTGF5b3V0U2FtcGxlTnVtQ29sdW1uczMuanBnIiAvPiA8aW1nCglzcmM9ImltYWdlcy9HcmlkRGF0YVNhbXBsZVNwYW4wNC5qcGciIC8+Cgo8cD5Ob3RlLCBob3dldmVyLCB0aGF0IGlmIHRoZSA8Y29kZT5ob3Jpem9udGFsQWxpZ25tZW50PC9jb2RlPiBvZgomcXVvdDtCdXR0b24gNSZxdW90OyB3YXMgPGNvZGU+RklMTDwvY29kZT4sIHRoZW4gdGhlIDxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+IHdvdWxkIG5vdCBoYXZlIGJlZW4KYWJsZSB0byBob25vciB0aGUgcmVxdWVzdCBmb3IgYSB3aWR0aCBvZiA3MCBwaXhlbHMuPC9wPgoKPHA+T25lIGZpbmFsIGNvbW1lbnQgYWJvdXQgdXNpbmcgd2lkdGggYW5kIGhlaWdodCBoaW50czogc29tZXRoaW5nCnRoYXQgbG9va3MgZ29vZCBvbiBvbmUgcGxhdGZvcm0gbWF5IG5vdCBsb29rIGdvb2Qgb24gYW5vdGhlci4gVGhlCnZhcmlhdGlvbiBiZXR3ZWVuIGZvbnQgc2l6ZXMgYW5kIG5hdHVyYWwgd2lkZ2V0IHNpemVzIGFjcm9zcyBwbGF0Zm9ybXMKbWVhbnMgdGhhdCBoYXJkLWNvZGluZyBwaXhlbCB2YWx1ZXMgaXMgbm90IHVzdWFsbHkgdGhlIGJlc3Qgd2F5IHRvIGxheQpvdXQgd2luZG93cy4gU28sIGtlZXAgdGhlIHVzZSBvZiBzaXplIGhpbnRzIHRvIGEgbWluaW11bSwgaWYgeW91IHVzZQp0aGVtIGF0IGFsbC48L3A+Cgo8aDM+QSBDb21wbGV4IEdyaWRMYXlvdXQgRXhhbXBsZTwvaDM+Cgo8cD5TbyBmYXIsIHRoZSA8Y29kZT5HcmlkTGF5b3V0PC9jb2RlPiBleGFtcGxlcyBoYXZlIGJlZW4gZmFpcmx5CnNpbXBsZSwgaW4gb3JkZXIgdG8gc2hvdyBob3cgZWFjaCBmaWVsZCB3b3Jrcy4gTm93LCB3ZSB3aWxsIHB1dCB0aGVtIGFsbAp0b2dldGhlciB0byBjcmVhdGUgYSBtb3JlIGNvbXBsaWNhdGVkIGV4YW1wbGUuIFdlIHN0YXJ0IGJ5IGhhbmQtZHJhd2luZwphIHJvdWdoIHNrZXRjaCBvZiB0aGUgd2luZG93IHdlIHdhbnQgdG8gY3JlYXRlLCB0byBkZXRlcm1pbmUgdGhpbmdzIGxpa2UKaG93IG1hbnkgY29sdW1ucyB0aGUgZ3JpZCBzaG91bGQgY29udGFpbiwgYW5kIHdoZXRoZXIgb3Igbm90IGFueSB3aWRnZXRzCm5lZWQgdG8gc3Bhbi48L3A+CjxpbWcgc3JjPSJpbWFnZXMvRG9nU2hvd0hhbmREcmF3bi5naWYiIC8+Cgo8cD5UaGVuIHdlIHN0YXJ0IGNvZGluZyB0aGUgZXhhbXBsZSBmcm9tIHRoZSBkaWFncmFtLiBUaGUgY29kZSBpcwpiZWxvdy4gTm90ZSB0aGF0IHdlIGhhdmUgYWRkZWQgYSBiaXQgb2YgbG9naWMgdG8gbWFrZSB0aGUgY29kZSBtb3JlCmludGVyZXN0aW5nLCBmb3IgZXhhbXBsZSwgJnF1b3Q7QnJvd3NlLi4uJnF1b3Q7IG9wZW5zIGEgPGNvZGU+RmlsZURpYWxvZzwvY29kZT4KdG8gcmVhZCBhbiA8Y29kZT5JbWFnZTwvY29kZT4gZmlsZSB3aGljaCB0aGUgPGNvZGU+Q2FudmFzPC9jb2RlPgpkaXNwbGF5cyBpbiBhIHBhaW50IGxpc3RlbmVyLCAmcXVvdDtEZWxldGUmcXVvdDsgZGVsZXRlcyB0aGUgPGNvZGU+SW1hZ2U8L2NvZGU+LCBhbmQKRW50ZXIgcHJpbnRzIHRoZSBjdXJyZW50IGRvZyBhbmQgb3duZXIgaW5mby48L3A+Cgo8cHJlPmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5EaXNwb3NlRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkRpc3Bvc2VMaXN0ZW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuUGFpbnRFdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuUGFpbnRMaXN0ZW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uQWRhcHRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuSW1hZ2U7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuUmVjdGFuZ2xlOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkRGF0YTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuR3JpZExheW91dDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkJ1dHRvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNhbnZhczsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbWJvOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuRGlzcGxheTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkZpbGVEaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Hcm91cDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkxhYmVsOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuTGlzdDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLlNoZWxsOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuVGV4dDsKCnB1YmxpYyBjbGFzcyBEb2dTaG93UmVnaXN0cmF0aW9uV2luZG93IHsKCVRleHQgZG9nTmFtZTsKCUNvbWJvIGRvZ0JyZWVkOwoJQ2FudmFzIGRvZ1Bob3RvOwoJSW1hZ2UgZG9nSW1hZ2U7CglMaXN0IGNhdGVnb3JpZXM7CglUZXh0IG93bmVyTmFtZTsKCVRleHQgb3duZXJQaG9uZTsKCglwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CgkJRGlzcGxheSBkaXNwbGF5ID0gbmV3IERpc3BsYXkoKTsKCQlTaGVsbCBzaGVsbCA9IG5ldyBEb2dTaG93UmVnaXN0cmF0aW9uV2luZG93KCkuY3JlYXRlU2hlbGwoZGlzcGxheSk7CgkJc2hlbGwub3BlbigpOwoJCXdoaWxlICghc2hlbGwuaXNEaXNwb3NlZCgpKSB7CgkJCWlmICghZGlzcGxheS5yZWFkQW5kRGlzcGF0Y2goKSkKCQkJCWRpc3BsYXkuc2xlZXAoKTsKCQl9Cgl9CgkKCXB1YmxpYyBTaGVsbCBjcmVhdGVTaGVsbChmaW5hbCBEaXNwbGF5IGRpc3BsYXkpIHsKCQlmaW5hbCBTaGVsbCBzaGVsbCA9IG5ldyBTaGVsbChkaXNwbGF5KTsKCQlzaGVsbC5zZXRUZXh0KCJEb2cgU2hvdyBFbnRyeSIpOwoJCUdyaWRMYXlvdXQgZ3JpZExheW91dCA9IG5ldyBHcmlkTGF5b3V0KCk7CgkJZ3JpZExheW91dC5udW1Db2x1bW5zID0gMzsKCQlzaGVsbC5zZXRMYXlvdXQoZ3JpZExheW91dCk7CgkJCgkJbmV3IExhYmVsKHNoZWxsLCBTV1QuTk9ORSkuc2V0VGV4dCgiRG9nJ3MgTmFtZToiKTsKCQkKCQlkb2dOYW1lID0gbmV3IFRleHQoc2hlbGwsIFNXVC5TSU5HTEUgfCBTV1QuQk9SREVSKTsKCQlHcmlkRGF0YSBncmlkRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0ZJTEwpOwoJCWdyaWREYXRhLmhvcml6b250YWxTcGFuID0gMjsKCQlkb2dOYW1lLnNldExheW91dERhdGEoZ3JpZERhdGEpOwoJCQoJCW5ldyBMYWJlbChzaGVsbCwgU1dULk5PTkUpLnNldFRleHQoIkJyZWVkOiIpOwoJCQoJCWRvZ0JyZWVkID0gbmV3IENvbWJvKHNoZWxsLCBTV1QuTk9ORSk7CgkJZG9nQnJlZWQuc2V0SXRlbXMobmV3IFN0cmluZ1tdIHsgIkNvbGxpZSIsICJQaXRidWxsIiwgIlBvb2RsZSIsCgkJCQkiU2NvdHRpZSIsICJCbGFjayBMYWIiIH0pOwoJCWRvZ0JyZWVkLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKEdyaWREYXRhLkhPUklaT05UQUxfQUxJR05fRklMTCkpOwoJCQoJCUxhYmVsIGxhYmVsID0gbmV3IExhYmVsKHNoZWxsLCBTV1QuTk9ORSk7CgkJbGFiZWwuc2V0VGV4dCgiQ2F0ZWdvcmllcyIpOwoJCWxhYmVsLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKEdyaWREYXRhLkhPUklaT05UQUxfQUxJR05fQ0VOVEVSKSk7CgkJCgkJbmV3IExhYmVsKHNoZWxsLCBTV1QuTk9ORSkuc2V0VGV4dCgiUGhvdG86Iik7CgkJZG9nUGhvdG8gPSBuZXcgQ2FudmFzKHNoZWxsLCBTV1QuQk9SREVSKTsKCQlncmlkRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0JPVEgpOwoJCWdyaWREYXRhLndpZHRoSGludCA9IDgwOwoJCWdyaWREYXRhLmhlaWdodEhpbnQgPSA4MDsKCQlncmlkRGF0YS52ZXJ0aWNhbFNwYW4gPSAzOwoJCWRvZ1Bob3RvLnNldExheW91dERhdGEoZ3JpZERhdGEpOwoJCWRvZ1Bob3RvLmFkZFBhaW50TGlzdGVuZXIobmV3IFBhaW50TGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHBhaW50Q29udHJvbChmaW5hbCBQYWludEV2ZW50IGV2ZW50KSB7CgkJCQlpZiAoZG9nSW1hZ2UgIT0gbnVsbCkgewoJCQkJCWV2ZW50LmdjLmRyYXdJbWFnZShkb2dJbWFnZSwgMCwgMCk7CgkJCQl9CgkJCX0KCQl9KTsKCQkKCQljYXRlZ29yaWVzID0gbmV3IExpc3Qoc2hlbGwsIFNXVC5NVUxUSSB8IFNXVC5CT1JERVIgfCBTV1QuVl9TQ1JPTEwpOwoJCWNhdGVnb3JpZXMuc2V0SXRlbXMobmV3IFN0cmluZ1tdIHsgIkJlc3Qgb2YgQnJlZWQiLCAiUHJldHRpZXN0IEZlbWFsZSIsCgkJCQkiSGFuZHNvbWVzdCBNYWxlIiwgIkJlc3QgRHJlc3NlZCIsICJGbHVmZmllc3QgRWFycyIsCgkJCQkiTW9zdCBDb2xvcnMiLCAiQmVzdCBQZXJmb3JtZXIiLCAiTG91ZGVzdCBCYXJrIiwKCQkJCSJCZXN0IEJlaGF2ZWQiLCAiUHJldHRpZXN0IEV5ZXMiLCAiTW9zdCBIYWlyIiwgIkxvbmdlc3QgVGFpbCIsCgkJCQkiQ3V0ZXN0IFRyaWNrIiB9KTsKCQlncmlkRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0ZJTEwKCQkJCXwgR3JpZERhdGEuVkVSVElDQUxfQUxJR05fRklMTCk7CgkJZ3JpZERhdGEudmVydGljYWxTcGFuID0gNDsKCQlpbnQgbGlzdEhlaWdodCA9IGNhdGVnb3JpZXMuZ2V0SXRlbUhlaWdodCgpICogMTI7CgkJUmVjdGFuZ2xlIHRyaW0gPSBjYXRlZ29yaWVzLmNvbXB1dGVUcmltKDAsIDAsIDAsIGxpc3RIZWlnaHQpOwoJCWdyaWREYXRhLmhlaWdodEhpbnQgPSB0cmltLmhlaWdodDsKCQljYXRlZ29yaWVzLnNldExheW91dERhdGEoZ3JpZERhdGEpOwoJCQoJCUJ1dHRvbiBicm93c2UgPSBuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCk7CgkJYnJvd3NlLnNldFRleHQoIkJyb3dzZS4uLiIpOwoJCWdyaWREYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkhPUklaT05UQUxfQUxJR05fRklMTCk7CgkJZ3JpZERhdGEuaG9yaXpvbnRhbEluZGVudCA9IDU7CgkJYnJvd3NlLnNldExheW91dERhdGEoZ3JpZERhdGEpOwoJCWJyb3dzZS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZXZlbnQpIHsKCQkJCVN0cmluZyBmaWxlTmFtZSA9IG5ldyBGaWxlRGlhbG9nKHNoZWxsKS5vcGVuKCk7CgkJCQlpZiAoZmlsZU5hbWUgIT0gbnVsbCkgewoJCQkJCWRvZ0ltYWdlID0gbmV3IEltYWdlKGRpc3BsYXksIGZpbGVOYW1lKTsKCQkJCX0KCQkJfQoJCX0pOwoJCQoJCUJ1dHRvbiBkZWxldGUgPSBuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCk7CgkJZGVsZXRlLnNldFRleHQoIkRlbGV0ZSIpOwoJCWdyaWREYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkhPUklaT05UQUxfQUxJR05fRklMTAoJCQkJfCBHcmlkRGF0YS5WRVJUSUNBTF9BTElHTl9CRUdJTk5JTkcpOwoJCWdyaWREYXRhLmhvcml6b250YWxJbmRlbnQgPSA1OwoJCWRlbGV0ZS5zZXRMYXlvdXREYXRhKGdyaWREYXRhKTsKCQlkZWxldGUuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGV2ZW50KSB7CgkJCQlpZiAoZG9nSW1hZ2UgIT0gbnVsbCkgewoJCQkJCWRvZ0ltYWdlLmRpc3Bvc2UoKTsKCQkJCQlkb2dJbWFnZSA9IG51bGw7CgkJCQkJZG9nUGhvdG8ucmVkcmF3KCk7CgkJCQl9CgkJCX0KCQl9KTsKCQkKCQlHcm91cCBvd25lckluZm8gPSBuZXcgR3JvdXAoc2hlbGwsIFNXVC5OT05FKTsKCQlvd25lckluZm8uc2V0VGV4dCgiT3duZXIgSW5mbyIpOwoJCWdyaWRMYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCWdyaWRMYXlvdXQubnVtQ29sdW1ucyA9IDI7CgkJb3duZXJJbmZvLnNldExheW91dChncmlkTGF5b3V0KTsKCQlncmlkRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0ZJTEwpOwoJCWdyaWREYXRhLmhvcml6b250YWxTcGFuID0gMjsKCQlvd25lckluZm8uc2V0TGF5b3V0RGF0YShncmlkRGF0YSk7CgkJCgkJbmV3IExhYmVsKG93bmVySW5mbywgU1dULk5PTkUpLnNldFRleHQoIk5hbWU6Iik7CgkJb3duZXJOYW1lID0gbmV3IFRleHQob3duZXJJbmZvLCBTV1QuU0lOR0xFIHwgU1dULkJPUkRFUik7CgkJb3duZXJOYW1lLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCkpOwoJCQoJCW5ldyBMYWJlbChvd25lckluZm8sIFNXVC5OT05FKS5zZXRUZXh0KCJQaG9uZToiKTsKCQlvd25lclBob25lID0gbmV3IFRleHQob3duZXJJbmZvLCBTV1QuU0lOR0xFIHwgU1dULkJPUkRFUik7CgkJb3duZXJQaG9uZS5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpKTsKCQkKCQlCdXR0b24gZW50ZXIgPSBuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCk7CgkJZW50ZXIuc2V0VGV4dCgiRW50ZXIiKTsKCQlncmlkRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0VORCk7CgkJZ3JpZERhdGEuaG9yaXpvbnRhbFNwYW4gPSAzOwoJCWVudGVyLnNldExheW91dERhdGEoZ3JpZERhdGEpOwoJCWVudGVyLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBldmVudCkgewoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJcbkRvZyBOYW1lOiAiICsgZG9nTmFtZS5nZXRUZXh0KCkpOwoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJEb2cgQnJlZWQ6ICIgKyBkb2dCcmVlZC5nZXRUZXh0KCkpOwoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJPd25lciBOYW1lOiAiICsgb3duZXJOYW1lLmdldFRleHQoKSk7CgkJCQlTeXN0ZW0ub3V0LnByaW50bG4oIk93bmVyIFBob25lOiAiICsgb3duZXJQaG9uZS5nZXRUZXh0KCkpOwoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJDYXRlZ29yaWVzOiIpOwoJCQkJU3RyaW5nIGNhdHNbXSA9IGNhdGVnb3JpZXMuZ2V0U2VsZWN0aW9uKCk7CgkJCQlmb3IgKGludCBpID0gMDsgaSA+IGNhdHMubGVuZ3RoOyBpKyspIHsKCQkJCQlTeXN0ZW0ub3V0LnByaW50bG4oIlx0IiArIGNhdHNbaV0pOwoJCQkJfQoJCQl9CgkJfSk7CgkJCgkJc2hlbGwuYWRkRGlzcG9zZUxpc3RlbmVyKG5ldyBEaXNwb3NlTGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldERpc3Bvc2VkKERpc3Bvc2VFdmVudCBhcmcwKSB7CgkJCQlpZiAoZG9nSW1hZ2UgIT0gbnVsbCkgewoJCQkJCWRvZ0ltYWdlLmRpc3Bvc2UoKTsKCQkJCQlkb2dJbWFnZSA9IG51bGw7CgkJCQl9CgkJCX0JCQkKCQl9KTsKCQkKCQlzaGVsbC5wYWNrKCk7CgkJCgkJcmV0dXJuIHNoZWxsOwoJfQp9PC9wcmU+CgoKPHA+SGVyZSBpcyB3aGF0IHRoZSB3aW5kb3cgbG9va3MgbGlrZSBhZnRlciBNYXJ5IFNtaXRoIGVudGVycwpCaWZmb3JkIGluIHRoZSBkb2cgc2hvdzo8L3A+CjxpbWcgc3JjPSJpbWFnZXMvRG9nU2hvd0JpZmYuanBnIiAvPgoKPHA+SWYgdGhpcyB3aW5kb3cgaXMgcmVzaXplZCBsYXJnZXIsIHRoZSBsYXlvdXQgYWRqdXN0cyBhcyBmb2xsb3dzOjwvcD4KCjxpbWcgc3JjPSJpbWFnZXMvRG9nU2hvd0JpZmZSZXNpemVkLmpwZyIgLz4KCjxwPk5vdGljZSB0aGUgZm9sbG93aW5nOjwvcD4KPHVsPgoJPGxpPlRoZXJlIGFyZSB0aHJlZSBjb2x1bW5zIGFuZCBzZXZlbiByb3dzLjwvbGk+Cgk8bGk+VGhlIDxjb2RlPmRvZ1Bob3RvPC9jb2RlPiA8Y29kZT5DYW52YXM8L2NvZGU+IGdyZXcgd2lkZXIgYW5kCgl0YWxsZXIgYmVjYXVzZSBpdCBpcyBmaWxsaW5nIGFuZCBncmFiYmluZyBob3Jpem9udGFsbHkgYW5kIHZlcnRpY2FsbHkKCSh3ZSBkaWQgbm90IHJlc2l6ZSB0aGUgPGNvZGU+SW1hZ2U8L2NvZGU+LCBidXQgd2UgY291bGQgaGF2ZSkuPC9saT4KCgk8bGk+VGhlIDxjb2RlPmRvZ0JyZWVkPC9jb2RlPiA8Y29kZT5Db21ibzwvY29kZT4gZ3JldyB3aWRlcgoJYmVjYXVzZSBpdCBpcyBmaWxsaW5nIGhvcml6b250YWxseSwgYW5kIGl0IGlzIGluIHRoZSBzYW1lIGNvbHVtbiBhcyB0aGUKCTxjb2RlPkNhbnZhczwvY29kZT4uPC9saT4KCgk8bGk+VGhlIDxjb2RlPmRvZ05hbWU8L2NvZGU+IDxjb2RlPlRleHQ8L2NvZGU+IGdyZXcgd2lkZXIgYmVjYXVzZQoJaXQgaXMgZmlsbGluZyBob3Jpem9udGFsbHksIGFuZCBvbmUgb2YgdGhlIGNvbHVtbnMgaXQgc3BhbnMgaXMgdGhlCgljb2x1bW4gY29udGFpbmluZyB0aGUgPGNvZGU+Q2FudmFzPC9jb2RlPi48L2xpPgoKCTxsaT5UaGUgPGNvZGU+Y2F0ZWdvcmllczwvY29kZT4gPGNvZGU+TGlzdDwvY29kZT4gZ3JldyB0YWxsZXIKCWJlY2F1c2UgaXQgaXMgZmlsbGluZyB2ZXJ0aWNhbGx5LCBhbmQgaXQgc3BhbnMgdGhlIHNhbWUgcm93cyB0aGF0IHRoZSA8Y29kZT5DYW52YXM8L2NvZGU+Cglkb2VzLjwvbGk+CgoJPGxpPkJlY2F1c2UgdGhlIDxjb2RlPmNhdGVnb3JpZXM8L2NvZGU+IDxjb2RlPkxpc3Q8L2NvZGU+IGdyZXcKCXRhbGxlciwgaXRzIHZlcnRpY2FsIHNjcm9sbGJhciBkaXNhcHBlYXJlZCAoaXQgZGlkIG5vdCBncm93IHdpZGVyKS48L2xpPgoKCTxsaT5UaGUgPGNvZGU+b3duZXJJbmZvPC9jb2RlPiA8Y29kZT5Hcm91cDwvY29kZT4gZ3JldyB3aWRlcgoJYmVjYXVzZSBpdCBpcyBmaWxsaW5nIGhvcml6b250YWxseSwgYW5kIG9uZSBvZiB0aGUgY29sdW1ucyBpdCBzcGFucyBpcwoJdGhlIGNvbHVtbiBjb250YWluaW5nIHRoZSA8Y29kZT5DYW52YXM8L2NvZGU+LjwvbGk+CgoJPGxpPlRoZSA8Y29kZT5vd25lckluZm88L2NvZGU+IDxjb2RlPkdyb3VwPC9jb2RlPiwgYXMgYSBzdWJjbGFzcwoJb2YgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiwgaGFzIGl0cyBvd24gPGNvZGU+R3JpZExheW91dDwvY29kZT4gd2l0aCAyCgljb2x1bW5zIGFuZCAyIHJvd3MuPC9saT4KCgk8bGk+VGhlIDxjb2RlPm93bmVyTmFtZTwvY29kZT4gYW5kIDxjb2RlPm93bmVyUGhvbmU8L2NvZGU+IDxjb2RlPlRleHRzPC9jb2RlPgoJZ3JldyB3aWRlciBiZWNhdXNlIHRoZSA8Y29kZT5Hcm91cDwvY29kZT4gZ3JldyB3aWRlciwgYW5kIHRoZXkgYXJlCglmaWxsaW5nIGFuZCBncmFiYmluZyBob3Jpem9udGFsbHkgaW4gdGhlIDxjb2RlPkdyb3VwPC9jb2RlPidzIDxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+LjwvbGk+CgoJPGxpPlRoZSA8Y29kZT5icm93c2U8L2NvZGU+IGFuZCA8Y29kZT5kZWxldGU8L2NvZGU+IDxjb2RlPkJ1dHRvbnM8L2NvZGU+CglhcmUgaW5kZW50ZWQgc2xpZ2h0bHksIGFuZCBiZWNhdXNlIHRoZXkgYm90aCBmaWxsIGhvcml6b250YWxseSwgdGhleQoJYXJlIHRoZSBzYW1lIHdpZHRoLjwvbGk+CgoJPGxpPlRoZSA8Y29kZT5kZWxldGU8L2NvZGU+IDxjb2RlPkJ1dHRvbjwvY29kZT4gaXMgdmVydGljYWxseQoJYWxpZ25lZCBhdCB0aGUgdG9wIG9mIGl0cyByb3cuPC9saT4KCgk8bGk+VGhlICZxdW90O0NhdGVnb3JpZXMmcXVvdDsgPGNvZGU+TGFiZWw8L2NvZGU+IGlzIGNlbnRlcmVkIG92ZXIKCXRoZSA8Y29kZT5jYXRlZ29yaWVzPC9jb2RlPiA8Y29kZT5MaXN0PC9jb2RlPi4KCTwvcD4KCTxsaT5UaGUgPGNvZGU+ZW50ZXI8L2NvZGU+IDxjb2RlPkJ1dHRvbjwvY29kZT4gaXMgaG9yaXpvbnRhbGx5CglhbGlnbmVkIHRvIHRoZSByaWdodCBvZiB0aGUgMyBjb2x1bW5zIGl0IHNwYW5zLjwvbGk+CgoJPGxpPlRoZSA8Y29kZT5kb2dQaG90bzwvY29kZT4gPGNvZGU+Q2FudmFzPC9jb2RlPiB3YXMgY3JlYXRlZCB3aXRoCgl3aWR0aCBhbmQgaGVpZ2h0IGhpbnRzIGJlY2F1c2Ugd2Ugd2FudCB0aGUgPGNvZGU+SW1hZ2U8L2NvZGU+IHRvIGJlIDgwCglwaXhlbHMgeCA4MCBwaXhlbHMsIGlmIHBvc3NpYmxlLjwvbGk+CgoJPGxpPlRoZSA8Y29kZT5jYXRlZ29yaWVzPC9jb2RlPiA8Y29kZT5MaXN0PC9jb2RlPiB3YXMgY3JlYXRlZCB3aXRoCglhIGhlaWdodCBoaW50IHRoYXQgd2FzIGJhc2VkIG9uIHRoZSA8Y29kZT5MaXN0PC9jb2RlPidzIGZvbnQgdGltZXMgMTIsCgliZWNhdXNlIHdlIHdhbnQgdHJ5IHRvIGdldCB0aGUgPGNvZGU+TGlzdDwvY29kZT4gdG8gc2hvdyAxMiBpdGVtcwoJaW5pdGlhbGx5LjwvbGk+CjwvdWw+Cgo8aDI+Rm9ybUxheW91dDwvaDI+Cgo8cD48Y29kZT5Gb3JtTGF5b3V0PC9jb2RlPiB3b3JrcyBieSBjcmVhdGluZyA8Y29kZT5Gb3JtQXR0YWNobWVudDwvY29kZT5zCmZvciBlYWNoIHNpZGUgb2YgdGhlIHdpZGdldCwgYW5kIHN0b3JpbmcgdGhlbSBpbiB0aGUgbGF5b3V0IGRhdGEuIEFuCmF0dGFjaG1lbnQgJ2F0dGFjaGVzJyBhIHNwZWNpZmljIHNpZGUgb2YgdGhlIHdpZGdldCBlaXRoZXIgdG8gYSBwb3NpdGlvbgppbiB0aGUgcGFyZW50IDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4gb3IgdG8gYW5vdGhlciB3aWRnZXQgd2l0aGluIHRoZQpsYXlvdXQuIFRoaXMgcHJvdmlkZXMgdHJlbWVuZG91cyBmbGV4aWJpbGl0eSB3aGVuIGxheWluZyBvdXQsIGFzIGl0CmFsbG93cyB5b3UgdG8gc3BlY2lmeSB0aGUgcGxhY2VtZW50IG9mIGluZGl2aWR1YWwgd2lkZ2V0cyB3aXRoaW4gdGhlCmxheW91dC48L3A+Cgo8aDM+Rm9ybUxheW91dCBDb25maWd1cmF0aW9uIEZpZWxkczwvaDM+Cgo8cD5UaGUgPGNvZGU+bWFyZ2luV2lkdGg8L2NvZGU+LCBhbmQgPGNvZGU+TWFyZ2luSGVpZ2h0PC9jb2RlPgpmaWVsZHMgaW4gPGNvZGU+Rm9ybUxheW91dDwvY29kZT4gYXJlIHNpbWlsYXIgdG8gdGhvc2UgaW4gPGNvZGU+R3JpZExheW91dDwvY29kZT4uCkxlZnQgYW5kIHJpZ2h0IG1hcmdpbnMgYXJlIGRlZmluZWQgYnkgPGNvZGU+bWFyZ2luV2lkdGg8L2NvZGU+LCBhbmQgdG9wCmFuZCBib3R0b20gbWFyZ2lucyBhcmUgZGVmaW5lZCBieSA8Y29kZT5tYXJnaW5IZWlnaHQ8L2NvZGU+LiBNYXJnaW5zIGNhbgphbHNvIGJlIGRlZmluZWQgb24gYSBwZXItd2lkZ2V0IGJhc2lzIGluIHRoZSBhdHRhY2htZW50cy4gPGNvZGU+Rm9ybUxheW91dDwvY29kZT4KbWFyZ2lucyBhcmUgemVybyBieSBkZWZhdWx0LjwvcD4KCjxwPlRvIHNldCB0aGUgbWFyZ2lucywgd2UgY3JlYXRlIGEgPGNvZGU+Rm9ybUxheW91dDwvY29kZT4sIGFuZCBzZXQKdGhlIG1hcmdpbiBmaWVsZHMuIFRoZSBmb2xsb3dpbmcgY29kZSB3aWxsIHNldCBhIG1hcmdpbiBvZiBmaXZlIHBpeGVscwphcm91bmQgYWxsIGZvdXIgc2lkZXMgb2YgdGhlIHBhcmVudCA8Y29kZT5Db21wb3NpdGU8L2NvZGU+OjwvcD4KCjxwcmU+RGlzcGxheSBkaXNwbGF5ID0gbmV3IERpc3BsYXkgKCk7ClNoZWxsIHNoZWxsID0gbmV3IFNoZWxsIChkaXNwbGF5KTsKRm9ybUxheW91dCBsYXlvdXQ9IG5ldyBGb3JtTGF5b3V0ICgpOwpsYXlvdXQubWFyZ2luSGVpZ2h0ID0gNTsKbGF5b3V0Lm1hcmdpbldpZHRoID0gNTsKc2hlbGwuc2V0TGF5b3V0KGxheW91dCk7PC9wcmU+Cgo8aDM+Rm9ybURhdGEgT2JqZWN0IEZpZWxkczwvaDM+Cgo8cD48Y29kZT5Gb3JtRGF0YTwvY29kZT4gb2JqZWN0cyBzcGVjaWZ5IGhvdyBlYWNoIHdpZGdldCBpbiBhIDxjb2RlPkZvcm1MYXlvdXQ8L2NvZGU+CndpbGwgYmUgbGFpZCBvdXQuIEVhY2ggPGNvZGU+Rm9ybURhdGE8L2NvZGU+IG9iamVjdCBkZWZpbmVzIHRoZQphdHRhY2htZW50cyBmb3IgYWxsIGZvdXIgc2lkZXMgb2YgdGhlIHdpZGdldC4gVGhlc2UgYXR0YWNobWVudHMgdGVsbAp3aGVyZSB0byBwb3NpdGlvbiBlYWNoIHNpZGUgb2YgdGhlIHdpZGdldC4gVG8gc2V0IGEgd2lkZ2V0J3MgPGNvZGU+Rm9ybURhdGE8L2NvZGU+Cm9iamVjdCwgeW91IHVzZSB0aGUgPGNvZGU+c2V0TGF5b3V0RGF0YShPYmplY3QpPC9jb2RlPiBtZXRob2QsIGZvciBleGFtcGxlOjwvcD4KCjxwcmU+QnV0dG9uIGJ1dHRvbjEgPSBuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCk7CmJ1dHRvbjEuc2V0VGV4dCgmcXVvdDtCMSZxdW90Oyk7CmJ1dHRvbjEuc2V0TGF5b3V0RGF0YShuZXcgRm9ybURhdGEoKSk7PC9wcmU+Cgo8cD5UaGlzIGNvZGUgY3JlYXRlcyBhIDxjb2RlPkZvcm1EYXRhPC9jb2RlPiBvYmplY3Qgd2l0aCBubwphdHRhY2htZW50cy4gSW4gdGhpcyBjYXNlLCBkZWZhdWx0IGF0dGFjaG1lbnRzIGFyZSBkZWZpbmVkLCB3aGljaApkZWZlYXRzIHRoZSB3aG9sZSBwdXJwb3NlIGFuZCB1dGlsaXR5IG9mIDxjb2RlPkZvcm1MYXlvdXQ8L2NvZGU+LiBUaGUKZGVmYXVsdCBhdHRhY2htZW50cyBhdHRhY2ggdGhlIHdpZGdldCB0byB0aGUgdG9wIGFuZCBsZWZ0IGVkZ2VzIG9mIHRoZQpwYXJlbnQgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPi4gSWYgZXZlcnkgd2lkZ2V0IGluIGEgPGNvZGU+Rm9ybUxheW91dDwvY29kZT4KdXNlZCB0aGUgZGVmYXVsdCBhdHRhY2htZW50cywgdGhleSB3b3VsZCBhbGwgYmUgbGFpZCBvdXQgb25lIG9uIHRvcCBvZgphbm90aGVyIGluIHRoZSB0b3AgbGVmdCBjb3JuZXIgb2YgdGhlIHBhcmVudCA8Y29kZT5Db21wb3NpdGU8L2NvZGU+LjwvcD4KCjxwPlRoZSA8Y29kZT5sZWZ0PC9jb2RlPiwgPGNvZGU+cmlnaHQ8L2NvZGU+LCA8Y29kZT50b3A8L2NvZGU+LCBhbmQKPGNvZGU+Ym90dG9tPC9jb2RlPiBmaWVsZHMgb2YgPGNvZGU+Rm9ybURhdGE8L2NvZGU+IHNwZWNpZnkgdGhlIDxjb2RlPkZvcm1BdHRhY2htZW50PC9jb2RlPgpvYmplY3RzIHRoYXQgYXJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgbGVmdCwgcmlnaHQsIHRvcCBhbmQgYm90dG9tIHNpZGVzCm9mIHRoZSB3aWRnZXQsIHJlc3BlY3RpdmVseS4gVGhlc2UgZmllbGRzIGFyZSBzZXQgaW4gdGhlIGZvbGxvd2luZwpleGFtcGxlOjwvcD4KCjxwcmU+Rm9ybURhdGEgZm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTsKZm9ybURhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KDAsNjApOwpmb3JtRGF0YS5ib3R0b20gPSBuZXcgRm9ybUF0dGFjaG1lbnQoMTAwLC01KTsKZm9ybURhdGEubGVmdCA9IG5ldyBGb3JtQXR0YWNobWVudCgyMCwwKTsKZm9ybURhdGEucmlnaHQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoMTAwLC0zKTsKYnV0dG9uMS5zZXRMYXlvdXREYXRhKGZvcm1EYXRhKTs8L3ByZT4gPGltZwoJc3JjPSJpbWFnZXMvRm9ybUxheW91dFNhbXBsZTAxLmpwZyIgLz4KCjxwPkEgPGNvZGU+Rm9ybUF0dGFjaG1lbnQ8L2NvZGU+IG9iamVjdCBkZWZpbmVzIHRoZSBhdHRhY2htZW50IG9mIGEKc3BlY2lmaWMgc2lkZSBvZiBhIHdpZGdldC4gVGhlcmUgYXJlIG1hbnkgd2F5cyB0aGF0IGEgc2lkZSBjYW4gYmUKYXR0YWNoZWQ6IHRvIGEgcG9zaXRpb24gaW4gdGhlIHBhcmVudCA8Y29kZT5Db21wb3NpdGU8L2NvZGU+LCB0byBhbiBlZGdlCm9mIHRoZSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+LCB0byB0aGUgYWRqYWNlbnQgc2lkZSBvZiBhbm90aGVyIHdpZGdldCwKdG8gdGhlIG9wcG9zaXRlIHNpZGUgb2YgYW5vdGhlciB3aWRnZXQsIG9yIGNlbnRlcmVkIG9uIGFub3RoZXIgd2lkZ2V0LgpBdHRhY2hpbmcgdG8gYSBwb3NpdGlvbiBwbGFjZXMgdGhlIHNpZGUgb2YgdGhlIHdpZGdldCBzbyB0aGF0IGl0IGlzCmFsd2F5cyBhdCBhIHBlcmNlbnRhZ2Ugb2YgdGhlIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4uIFRvIGF0dGFjaCB0byBhbgplZGdlIG9mIHRoZSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+LCB0aGUgcGVyY2VudGFnZSBpcyBlaXRoZXIgMCUgb3IgMTAwJS4KQXR0YWNoaW5nIHRvIHRoZSBhZGphY2VudCBzaWRlIG9mIGFub3RoZXIgd2lkZ2V0IGVuc3VyZXMgdGhhdCB0aGUKc3BlY2lmaWVkIHNpZGUgb2YgdGhlIHdpZGdldCBpcyBhbHdheXMgbmV4dCB0byB0aGUgY2xvc2VzdCBzaWRlIG9mIHRoZQpvdGhlciB3aWRnZXQuIEF0dGFjaGluZyB0byB0aGUgb3Bwb3NpdGUgc2lkZSBvZiBhbm90aGVyIHdpZGdldCBlbnN1cmVzCnRoYXQgdGhlIHNwZWNpZmljIHNpZGUgb2YgdGhlIHdpZGdldCBpcyBhbGlnbmVkIHdpdGggdGhlIGZ1cnRoZXN0IHNpZGUKb2YgdGhlIG90aGVyIHdpZGdldC4gRmluYWxseSwgYXR0YWNoaW5nIHRvIHRoZSBjZW50ZXIgb2YgYW5vdGhlciB3aWRnZXQKY2VudGVycyB0aGUgd2lkZ2V0IG9uIHRoZSBvdGhlciB3aWRnZXQuIEFueSBvZiB0aGVzZSB3YXlzIGNhbiBiZSBkb25lCndpdGggb3Igd2l0aG91dCBhbiBvZmZzZXQuPC9wPgoKPHA+VGhlIDxjb2RlPndpZHRoPC9jb2RlPiBhbmQgPGNvZGU+aGVpZ2h0PC9jb2RlPiBmaWVsZHMgb2YgPGNvZGU+Rm9ybURhdGE8L2NvZGU+CnNwZWNpZnkgdGhlIHJlcXVlc3RlZCB3aWR0aCBhbmQgdGhlIGhlaWdodCBvZiB0aGUgd2lkZ2V0LiBJZiBhIHJlcXVlc3RlZAp3aWR0aCBvciBoZWlnaHQgY29uZmxpY3RzIHdpdGggY29uc3RyYWludHMgc2V0IGJ5IHRoZSBhdHRhY2htZW50cywgdGhlbgp0aGF0IHdpZHRoIG9yIGhlaWdodCB3aWxsIG5vdCBiZSBob25vcmVkLiBBbHRob3VnaCBzZXR0aW5nIGF0dGFjaG1lbnRzIGNhbgphbHNvIGRldGVybWluZSB3aWR0aCBhbmQgaGVpZ2h0LCB0aGVyZSBhcmUgc29tZSBjYXNlcyB3aGVuIHlvdSBkbyBub3QKd2FudCB0byBkZWZpbmUgYXR0YWNobWVudHMgZm9yIGFsbCBzaWRlcyBvZiB0aGUgd2lkZ2V0LiBJbiB0aGlzIGNhc2UsIGl0Cm1heSBiZSB1c2VmdWwgdG8gc2V0IHRoZSB3aWR0aCBhbmQgaGVpZ2h0IG9mIHRoZSB3aWRnZXQgYXMgZm9sbG93czo8L3A+Cgo8cHJlPkZvcm1EYXRhIGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKDIwLDMwKTsKZm9ybURhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KDAsNjApOwpmb3JtRGF0YS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KDIwLDApOwpidXR0b24xLnNldExheW91dERhdGEoZm9ybURhdGEpOzwvcHJlPiAKCjxwPklmIHlvdSB3aXNoIHRvIHNldCBvbmx5IHRoZSB3aWR0aCBvciB0aGUgaGVpZ2h0LCB5b3UgY2FuIGRpcmVjdGx5CnNldCB0aGUgd2lkdGggb3IgaGVpZ2h0IGZpZWxkIGluIHRoZSA8Y29kZT5Gb3JtRGF0YTwvY29kZT4gb2JqZWN0OjwvcD4KCjxwcmU+Rm9ybURhdGEgZm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTsKZm9ybURhdGEud2lkdGggPSAzMDsKZm9ybURhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KDAsNjApOw0KZm9ybURhdGEuYm90dG9tID0gbmV3IEZvcm1BdHRhY2htZW50KDEwMCwtNSk7CmZvcm1EYXRhLmxlZnQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoMjAsMCk7CmJ1dHRvbjEuc2V0TGF5b3V0RGF0YShmb3JtRGF0YSk7PC9wcmU+IAoKPHA+Tm90ZSB0aGF0IGlmIGEgYnV0dG9uIGlzIGF0dGFjaGVkIHRvIHRoZSBwYXJlbnQgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPgpvbiBib3RoIHNpZGVzLCB3aGVuIHRoZSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IGlzIHJlc2l6ZWQsIHRoZSBidXR0b24Kd2lsbCBncm93IG9yIHNocmluayBhbG9uZyB3aXRoIGl0LjwvcD4KCjxoMz5Gb3JtQXR0YWNobWVudCBPYmplY3RzPC9oMz4KCjxwPkEgPGNvZGU+Rm9ybUF0dGFjaG1lbnQ8L2NvZGU+IGlzIGFuIG9iamVjdCB0aGF0IGRlZmluZXMgdGhlCmF0dGFjaG1lbnQgZm9yIGEgc3BlY2lmaWMgc2lkZSBvZiBhIHdpZGdldC4gSXQgaXMgbm90IGFsd2F5cyBuZWNlc3NhcnkKdG8gc2V0IGFuIGF0dGFjaG1lbnQgZm9yIGFsbCBmb3VyIHNpZGVzIG9mIGEgd2lkZ2V0LiBPZnRlbiwgc3BlY2lmeWluZwpvbmUgb3IgbW9yZSBzaWRlcyBvZiBhIHdpZGdldCBjYW4gZnVsbHkgc3BlY2lmeSBpdHMgcGxhY2VtZW50IGluIHRoZQpsYXlvdXQuIEluIG9yZGVyIHRvIHByb3Blcmx5IHBsYWNlIHlvdXIgd2lkZ2V0cywgeW91IHNob3VsZCBkZWZpbmUgYW4KYXR0YWNobWVudCBmb3IgYXQgbGVhc3Qgb25lIG9mIDxjb2RlPmxlZnQ8L2NvZGU+IG9yIDxjb2RlPnJpZ2h0PC9jb2RlPgppbiB0aGUgPGNvZGU+Rm9ybURhdGE8L2NvZGU+LCBhbmQgYXQgbGVhc3Qgb25lIG9mIDxjb2RlPnRvcDwvY29kZT4gb3IgPGNvZGU+Ym90dG9tPC9jb2RlPi4KSWYgeW91IG9ubHkgd2lzaCB0byBhdHRhY2ggdGhlIGxlZnQgc2lkZSBvZiBhIHdpZGdldCBhbmQgbm90IHRoZSByaWdodCwKdGhlbiB0aGUgd2lkZ2V0IHdpbGwgYmUgcG9zaXRpb25lZCBiYXNlZCBvbiBpdHMgbGVmdCBzaWRlLCBhbmQgdGhlCndpZGdldCB3aWxsIHRha2UgaXRzIG5hdHVyYWwgc2l6ZSAob3IgaXRzIHJlcXVlc3RlZCBzaXplLCBpZiBvbmUgd2FzIHNldApmb3IgaXQpLiBJZiB5b3UgZG8gbm90IGF0dGFjaCB0aGUgbGVmdCBvciB0aGUgcmlnaHQsIGRlZmF1bHQgcG9zaXRpb25pbmcKd2lsbCBhdHRhY2ggeW91ciB3aWRnZXQgdG8gdGhlIGxlZnQgc2lkZSBvZiB0aGUgZm9ybS4gVGhlIHNhbWUgbG9naWMKYXBwbGllcyBmb3IgdGhlIHRvcCBhbmQgYm90dG9tIHNpZGVzLjwvcD4KCjxoMz5BdHRhY2hpbmcgdG8gYSBQb3NpdGlvbjwvaDM+CjxwPlRoZXJlIGFyZSBtYW55IHR5cGVzIG9mIGF0dGFjaG1lbnQuIFRoZSBmaXJzdCBpcyB0byBhdHRhY2ggdGhlCndpZGdldCB0byBhIHBvc2l0aW9uIGluIHRoZSBwYXJlbnQgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPi4gVGhpcyBjYW4gYmUKZG9uZSBieSBkZWZpbmluZyBhIHBlcmNlbnRhZ2UgdmFsdWUgb3V0IG9mIDEwMCwgZm9yIGV4YW1wbGU6PC9wPgoKPHByZT5Gb3JtRGF0YSBmb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpOwpmb3JtRGF0YS50b3AgPSBuZXcgRm9ybUF0dGFjaG1lbnQoNTAsMCk7CmJ1dHRvbjEuc2V0TGF5b3V0RGF0YShmb3JtRGF0YSk7PC9wcmU+IDxpbWcKCXNyYz0iaW1hZ2VzL0Zvcm1MYXlvdXRTYW1wbGVQb3NpdGlvbjUwLmpwZyIgLz4KCjxwPlRoaXMgc2V0cyB0aGUgdG9wIG9mIHRoZSA8Y29kZT5CdXR0b248L2NvZGU+IHRvIGEgcG9zaXRpb24gdGhhdApyZXByZXNlbnRzIDUwJSBvZiB0aGUgaGVpZ2h0IG9mIHRoZSBwYXJlbnQgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiAoYSA8Y29kZT5TaGVsbDwvY29kZT4pLAp3aXRoIGFuIG9mZnNldCBvZiAwLiBXaGVuIHRoZSBzaGVsbCBpcyByZXNpemVkLCB0aGUgdG9wIHNpZGUgb2YgdGhlIDxjb2RlPkJ1dHRvbjwvY29kZT4Kd2lsbCBzdGlsbCBiZSBhdCA1MCUsIGxpa2Ugc286PC9wPgoKPGltZyBzcmM9ImltYWdlcy9Gb3JtTGF5b3V0U2FtcGxlUG9zaXRpb241MFJlc2l6ZWQuanBnIiAvPgoKPHA+SWYgd2UgY2hvc2UgdG8gc2V0IGFuIG9mZnNldCB2YWx1ZSwgdGhlIHRvcCBzaWRlIG9mIHRoZSA8Y29kZT5CdXR0b248L2NvZGU+CndvdWxkIGhhdmUgYmVlbiBzZXQgdG8gNTAlIG9mIHRoZSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IHBsdXMgb3IgbWludXMKdGhlIG51bWJlciBvZiBwaXhlbHMgc2V0IGZvciB0aGUgb2Zmc2V0LjwvcD4KCjxwPldlIGNhbiBhbHNvIGRlZmluZSB0aGUgcG9zaXRpb24gb2YgdGhlIGJ1dHRvbiB1c2luZyBhbiBhcmJpdHJhcnkgc2NhbGUsIGZvciBleGFtcGxlOjwvcD4KCjxwcmU+Rm9ybURhdGEgZm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTsKZm9ybURhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KDMwLDcwLDEwKTsKYnV0dG9uMS5zZXRMYXlvdXREYXRhKGZvcm1EYXRhKTs8L3ByZT4KCjxwPklmIHRoZSBoZWlnaHQgb2YgdGhlIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4gaXMgZGVmaW5lZCBhcyBiZWluZwo3MCB1bml0cywgdGhpcyBzZXRzIHRoZSB0b3Agb2YgdGhlIDxjb2RlPkJ1dHRvbjwvY29kZT4gdG8gYSBwb3NpdGlvbgpyZXByZXNlbnRpbmcgMzAgdW5pdHMgZG93biBmcm9tIHRoZSB0b3Agb2YgdGhlIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4sCnBsdXMgMTAgcGl4ZWxzIChpLmUuIDMvN3RocyBvZiB0aGUgaGVpZ2h0IG9mIHRoZSBjb21wb3NpdGUgcGx1cyAxMCBwaXhlbHMpLjwvcD4KCjxwPlRvIGF0dGFjaCBhIHNpZGUgb2YgYSB3aWRnZXQgdG8gYW4gZWRnZSBvZgp0aGUgcGFyZW50IDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4sIHNldCB0aGUgcG9zaXRpb24gdG8gZWl0aGVyIDAlIG9yIDEwMCUuIFRoZSAwCnBvc2l0aW9uIGlzIGRlZmluZWQgYXMgdGhlIHRvcCBvZiB0aGUgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiB3aGVuIGdvaW5nCnZlcnRpY2FsbHksIGFuZCB0aGUgbGVmdCB3aGVuIGdvaW5nIGhvcml6b250YWxseS4gVGhlIHJpZ2h0IGFuZCBib3R0b20KZWRnZXMgb2YgdGhlIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4gYXJlIGRlZmluZWQgYXMgdGhlIDEwMCBwb3NpdGlvbi4KVGhlcmVmb3JlLCBpZiB3ZSB3YW50IHRvIGF0dGFjaCBhIHdpZGdldCB0byB0aGUgcmlnaHQgZWRnZSBvZiB0aGUgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiwKd2Ugc2ltcGx5IGhhdmUgdG8gY3JlYXRlIGFuIGF0dGFjaG1lbnQgdGhhdCBzZXRzIHRoZSBwb3NpdGlvbiB0byAxMDA6PC9wPgoKPHByZT5Gb3JtRGF0YSBmb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpOwpmb3JtRGF0YS5yaWdodCA9IG5ldyBGb3JtQXR0YWNobWVudCgxMDAsLTUpOwpidXR0b24xLnNldExheW91dERhdGEoZm9ybURhdGEpOzwvcHJlPiA8aW1nCglzcmM9ImltYWdlcy9Gb3JtTGF5b3V0U2FtcGxlUGFyZW50MTAwLmpwZyIgLz4KCjxwPlRoaXMgYXR0YWNoZXMgdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIDxjb2RlPkJ1dHRvbjwvY29kZT4gdG8gdGhlCnJpZ2h0IGVkZ2Ugb2YgdGhlIHBhcmVudCAoYSA8Y29kZT5TaGVsbDwvY29kZT4pLCB3aXRoIGFuIG9mZnNldCBvZiBmaXZlCnBpeGVscy4gTm90ZSB0aGF0IHRoZSBvZmZzZXRzIGdvIGluIG9uZSBkaXJlY3Rpb24gb25seS4gSWYgeW91IHdhbnQgYQp3aWRnZXQgb2Zmc2V0IGRvd24gb3IgdG8gdGhlIHJpZ2h0LCB0aGUgb2Zmc2V0IHNob3VsZCBiZSBwb3NpdGl2ZS4gRm9yCm9mZnNldHMgdGhhdCBzaGlmdCB0aGUgd2lkZ2V0IHVwIG9yIHRvIHRoZSBsZWZ0LCB0aGUgb2Zmc2V0IHNob3VsZCBiZQpuZWdhdGl2ZS4gV2hlbiB0aGUgPGNvZGU+U2hlbGw8L2NvZGU+IGlzIHJlc2l6ZWQsIHRoZSA8Y29kZT5CdXR0b248L2NvZGU+CndpbGwgYWx3YXlzIGJlIGZpdmUgcGl4ZWxzIGF3YXkgZnJvbSB0aGUgcmlnaHQgZWRnZTo8L3A+Cgo8aW1nIHNyYz0iaW1hZ2VzL0Zvcm1MYXlvdXRTYW1wbGVQYXJlbnQxMDBSZXNpemVkLmpwZyIgLz4KCjxoMz5BdHRhY2hpbmcgdG8gQW5vdGhlciBXaWRnZXQ8L2gzPgo8cD5UaGUgdGhpcmQgdHlwZSBvZiBhdHRhY2htZW50IGlzIHRvIGF0dGFjaCB0aGUgc2lkZSBvZiB0aGUgd2lkZ2V0CnRvIGFub3RoZXIgY29udHJvbCB3aXRoaW4gdGhlIHBhcmVudCA8Y29kZT5Db21wb3NpdGU8L2NvZGU+LiBUaGUgc2lkZQpjYW4gYmUgYXR0YWNoZWQgdG8gdGhlIGFkamFjZW50IHNpZGUgb2YgdGhlIG90aGVyIGNvbnRyb2wgKHRoZSBkZWZhdWx0KSwKdG8gdGhlIG9wcG9zaXRlIHNpZGUgb2YgdGhlIG90aGVyIGNvbnRyb2wsIG9yIHRoZSB3aWRnZXQgY2FuIGJlIGNlbnRlcmVkCm9uIHRoZSBvdGhlciBjb250cm9sLCBhbGwgd2l0aCBvciB3aXRob3V0IGFuZCBvZmZzZXQuPC9wPgoKPHA+VGhlIG1vc3QgY29tbW9uIHdheSB0byBhdHRhY2ggdG8gYW5vdGhlciBjb250cm9sIGlzIHRvIGF0dGFjaCB0bwppdHMgYWRqYWNlbnQgc2lkZS4gRm9yIGV4YW1wbGUsIHRoZSBmb2xsb3dpbmcgY29kZTo8L3A+Cgo8cHJlPkZvcm1EYXRhIGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7CmZvcm1EYXRhLnRvcCA9IG5ldyBGb3JtQXR0YWNobWVudCgyMCwwKTsKYnV0dG9uMS5zZXRMYXlvdXREYXRhKGZvcm1EYXRhKTsKCkZvcm1EYXRhIGZvcm1EYXRhMiA9IG5ldyBGb3JtRGF0YSgpOwpmb3JtRGF0YTIudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KGJ1dHRvbjEsMTApOwpidXR0b24yLnNldExheW91dERhdGEoZm9ybURhdGEyKTs8L3ByZT4gPGltZwoJc3JjPSJpbWFnZXMvRm9ybUxheW91dFNhbXBsZUF0dGFjaFdpZGdldDAxLmpwZyIgLz4KCjxwPlRoaXMgZXhhbXBsZSBhdHRhY2hlcyB0aGUgdG9wIG9mIGJ1dHRvbjIgdG8gdGhlIGJvdHRvbSBvZgpidXR0b24xLiBOb3RlIHRoYXQgd2hlbiB0aGUgd2luZG93IGlzIHJlc2l6ZWQsIGJ1dHRvbjEgd2lsbCBtb3ZlIHNvIHRoYXQKaXRzIHRvcCBzaWRlIGlzIGFsd2F5cyBwb3NpdGlvbmVkIGF0IDIwJSBvZiB0aGUgPGNvZGU+U2hlbGw8L2NvZGU+LCBhbmQKYnV0dG9uMiB3aWxsIG1vdmUgc28gdGhhdCBpdHMgdG9wIHNpZGUgaXMgYWx3YXlzIDEwIHBpeGVscyBiZWxvdyB0aGUKYWRqYWNlbnQgKGJvdHRvbSkgc2lkZSBvZiBidXR0b24xLjwvcD4KCjxpbWcgc3JjPSJpbWFnZXMvRm9ybUxheW91dFNhbXBsZUF0dGFjaFdpZGdldDAxUmVzaXplZC5qcGciIC8+Cgo8cD5XaGlsZSB0aGUgZGVmYXVsdCBpcyB0byBhdHRhY2ggdGhlIHNpZGUgb2YgYSB3aWRnZXQgdG8gdGhlCmFkamFjZW50IHNpZGUgb2YgYSBjb250cm9sLCA8Y29kZT5Gb3JtQXR0YWNobWVudDwvY29kZT5zIGNhbiBhbHNvIGJlCmNyZWF0ZWQgdG8gYXR0YWNoIHRvIHRoZSBvcHBvc2l0ZSBzaWRlIG9mIGEgY29udHJvbC4gVGhpcyBpcyB1c2VmdWwgd2hlbgpsaW5pbmcgdXAgd2lkZ2V0cy4gSW4gdGhpcyBjYXNlLCB5b3UgY3JlYXRlIHRoZSBhdHRhY2htZW50IHRvIHRoZSBvdGhlcgpjb250cm9sIHVzaW5nIDxjb2RlPlRPUDwvY29kZT4sIDxjb2RlPkJPVFRPTTwvY29kZT4sIDxjb2RlPkxFRlQ8L2NvZGU+Cm9yIDxjb2RlPlJJR0hUPC9jb2RlPiBhbGlnbm1lbnQsIGZvciBleGFtcGxlOjwvcD4KCjxwcmU+Zm9ybURhdGEyLnRvcCA9IG5ldyBGb3JtQXR0YWNobWVudChidXR0b24xLDAsU1dULlRPUCk7PC9wcmU+Cgo8cD5JbiB0aGUgZm9sbG93aW5nIGV4YW1wbGUsIHRoZSB0b3Agc2lkZSBvZiA8Y29kZT5idXR0b24xPC9jb2RlPiBpcyBwb3NpdGlvbmVkCmF0IDIwJSBvZiB0aGUgPGNvZGU+U2hlbGw8L2NvZGU+LiA8Y29kZT5idXR0b24yPC9jb2RlPidzIHRvcCBzaWRlIGlzIGFsaWduZWQgd2l0aAo8Y29kZT5idXR0b24xPC9jb2RlPidzIHRvcCBzaWRlLCB1c2luZyA8Y29kZT5UT1A8L2NvZGU+IGFsaWdubWVudC4gVGhpcyBtZWFucyB0aGF0IHRoZSB0b3Agc2lkZSBvZgo8Y29kZT5idXR0b24yPC9jb2RlPiBpcyBhbHNvIHBvc2l0aW9uZWQgYXQgMjAlIG9mIHRoZSA8Y29kZT5TaGVsbDwvY29kZT4uIE5vdGUgdGhhdAp3aGVuIHNwZWNpZnlpbmcgdGhlIHRvcCBhdHRhY2htZW50LCBvbmx5IHRoZSB2ZXJ0aWNhbCBwbGFjZW1lbnQgb2YgdGhlCndpZGdldCBpcyBiZWluZyBkZWZpbmVkLiBJdCBpcyBzdGlsbCBuZWNlc3NhcnkgdG8gc2V0IHRoZSBsZWZ0CmF0dGFjaG1lbnQgZm9yIDxjb2RlPmJ1dHRvbjI8L2NvZGU+IHNvIHRoYXQgdGhlIDxjb2RlPkJ1dHRvbjwvY29kZT5zIGFyZSBub3Qgc3RhY2tlZApvbiB0b3Agb2YgZWFjaCBvdGhlci48L3A+Cgo8cHJlPkZvcm1EYXRhIGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKDUwLDUwKTsKZm9ybURhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KDIwLDApOwpidXR0b24xLnNldExheW91dERhdGEoZm9ybURhdGEpOwoNCkZvcm1EYXRhIGZvcm1EYXRhMiA9IG5ldyBGb3JtRGF0YSgpOwpmb3JtRGF0YTIubGVmdCA9IG5ldyBGb3JtQXR0YWNobWVudChidXR0b24xLDUpOwpmb3JtRGF0YTIudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KGJ1dHRvbjEsMCxTV1QuVE9QKTsgCmJ1dHRvbjIuc2V0TGF5b3V0RGF0YShmb3JtRGF0YTIpOzwvcHJlPiA8aW1nCglzcmM9ImltYWdlcy9Gb3JtTGF5b3V0U2FtcGxlQXR0YWNoV2lkZ2V0MDIuanBnIiAvPgoKPHA+VGhlIGZpbmFsIHdheSB0byBhdHRhY2ggYSB3aWRnZXQgdG8gYW5vdGhlciBjb250cm9sIGlzIHRvIGNlbnRlcgppdCBvbiB0aGUgb3RoZXIgY29udHJvbC4gVGhpcyBpcyB1c2VmdWwgd2hlbiB0aGUgd2lkZ2V0cyBhcmUgZGlmZmVyZW50CnNpemVzLiBJbiB0aGlzIGNhc2UsIHlvdSBjcmVhdGUgdGhlIGF0dGFjaG1lbnQgdG8gdGhlIG90aGVyIGNvbnRyb2wgd2l0aAo8Y29kZT5DRU5URVI8L2NvZGU+IGFsaWdubWVudCwgZm9yIGV4YW1wbGU6PC9wPgoKPHByZT5mb3JtRGF0YS50b3AgPSBuZXcgRm9ybUF0dGFjaG1lbnQoYnV0dG9uMSwwLFNXVC5DRU5URVIpOzwvcHJlPgoKPHA+VGhpcyB3aWxsIHBsYWNlIHRoZSB0b3Agb2YgdGhlIHdpZGdldCBpbiBhIHBvc2l0aW9uIHRoYXQgd2lsbAphbGxvdyB0aGUgd2lkZ2V0IHRvIGJlIGNlbnRlcmVkIG9uIHRoZSBvdGhlciBjb250cm9sLCB3aXRoIGFuIG9mZnNldCBvZgowLiBTZXR0aW5nIG9ubHkgdGhlIHRvcCwgb3IgdGhlIGJvdHRvbSwgb3IgYm90aCBhcyBhIGNlbnRlciBhdHRhY2htZW50CndpbGwgcHJvZHVjZSB0aGUgc2FtZSByZXN1bHQuIFRoZSB0b3Agc2lkZSBvZiB0aGUgd2lkZ2V0IGlzIG5vdApjZW50ZXJlZCwgYnV0IHRoZSBlbnRpcmUgd2lkZ2V0IGlzIGNlbnRlcmVkLCBzbyB0aGlzIG9ubHkgbmVlZHMgdG8gYmUKc3BlY2lmaWVkIG9uY2UuIEhlcmUgaXMgYW4gZXhhbXBsZTo8L3A+Cgo8cHJlPkZvcm1EYXRhIGZvcm1EYXRhMSA9IG5ldyBGb3JtRGF0YSAoNTAsNTApOw0KYnV0dG9uMS5zZXRMYXlvdXREYXRhKGZvcm1EYXRhMSk7CgpGb3JtRGF0YSBmb3JtRGF0YTIgPSBuZXcgRm9ybURhdGEgKCk7CmZvcm1EYXRhMi5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50IChidXR0b24xLDUpOwpmb3JtRGF0YTIudG9wID0gbmV3IEZvcm1BdHRhY2htZW50IChidXR0b24xLDAsU1dULkNFTlRFUik7CmJ1dHRvbjIuc2V0TGF5b3V0RGF0YShmb3JtRGF0YTIpOzwvcHJlPiA8aW1nCglzcmM9ImltYWdlcy9Gb3JtTGF5b3V0U2FtcGxlQXR0YWNoV2lkZ2V0MDMuanBnIiAvPgoKPHA+VXNpbmcgdGhlIGRpZmZlcmVudCB0eXBlcyBvZiA8Y29kZT5Gb3JtQXR0YWNobWVudDwvY29kZT4gYWxsb3dzCmxheW91dHMgdG8gYmUgZGVmaW5lZCBpbiBtYW55IGRpZmZlcmVudCB3YXlzLiA8Y29kZT5Gb3JtTGF5b3V0PC9jb2RlPgpjb3ZlcnMgY2VydGFpbiBjYXNlcyB0aGF0IGNhbm5vdCBiZSBzb2x2ZWQgdXNpbmcgPGNvZGU+RmlsbExheW91dDwvY29kZT4sCjxjb2RlPlJvd0xheW91dDwvY29kZT4gb3IgPGNvZGU+R3JpZExheW91dDwvY29kZT4sIG1ha2luZyBpdCBhIHZlcnkKdXNlZnVsIGNsYXNzIGZvciBkZWZpbmluZyBsYXlvdXRzLjwvcD4KCjxwPjxiPkltcG9ydGFudDogPC9iPkRvIDxiPm5vdDwvYj4gZGVmaW5lIGNpcmN1bGFyCmF0dGFjaG1lbnRzLiBGb3IgZXhhbXBsZSwgZG8gbm90IGF0dGFjaCB0aGUgcmlnaHQgZWRnZSBvZiBidXR0b24xCnRvIHRoZSBsZWZ0IGVkZ2Ugb2YgYnV0dG9uMiBhbmQgdGhlbiBhdHRhY2ggdGhlIGxlZnQgZWRnZSBidXR0b24yIHRvIHRoZQpyaWdodCBlZGdlIG9mIGJ1dHRvbjEuIFRoaXMgd2lsbCBvdmVyLWNvbnN0cmFpbiB0aGUgbGF5b3V0LCBjYXVzaW5nCnVuZGVmaW5lZCBiZWhhdmlvci4gVGhlIGFsZ29yaXRobSB3aWxsIHRlcm1pbmF0ZSwgYnV0IHRoZSByZXN1bHRzCmFyZSB1bmRlZmluZWQuIFRoZXJlZm9yZSwgbWFrZSBzdXJlIHRoYXQgeW91IGRvIG5vdCBvdmVyLWNvbnN0cmFpbiB5b3VyCndpZGdldHMuIE9ubHkgcHJvdmlkZSB0aGUgYXR0YWNobWVudHMgbmVjZXNzYXJ5IHRvIHByb3Blcmx5IGxheSBvdXQgdGhlCndpZGdldHMuPC9wPgoKPGgzPkEgRm9ybUxheW91dCBFeGFtcGxlPC9oMz4KCjxwPlNvIGZhciwgYWxsIHRoZSBleGFtcGxlcyB1c2luZyA8Y29kZT5Gb3JtTGF5b3V0PC9jb2RlPiBoYXZlCmludm9sdmVkIG9uZSBvciB0d28gPGNvZGU+QnV0dG9uPC9jb2RlPnMsIHRvIHNob3cgaG93IDxjb2RlPkZvcm1BdHRhY2htZW50PC9jb2RlPnMKd29yay4gTmV4dCwgd2Ugd2lsbCBkbyBhIHNpbXBsZSBleGFtcGxlIHVzaW5nIG1vcmUgPGNvZGU+QnV0dG9uPC9jb2RlPnMKdG8gc2hvdyBob3cgYSBsYXlvdXQgY2FuIGJlIGFycmFuZ2VkIHVzaW5nIHRoZSBhdHRhY2htZW50cy4gV2UnbGwgc3RhcnQKYnkgZHJhd2luZyBhIGJhc2ljIGRpYWdyYW0gb3V0bGluaW5nIHRoZSBhdHRhY2htZW50cyB0aGF0IHdlIHdpc2ggdG8KY3JlYXRlLjwvcD4KoKCgoCA8aW1nIHNyYz0iaW1hZ2VzL0Zvcm1FeGFtcGxlSGFuZERyYXduLmpwZyIgLz4gCgo8cHJlPkZvcm1EYXRhIGRhdGExID0gbmV3IEZvcm1EYXRhKCk7CmRhdGExLmxlZnQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoMCw1KTsKZGF0YTEucmlnaHQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoMjUsMCk7CmJ1dHRvbjEuc2V0TGF5b3V0RGF0YShkYXRhMSk7CgpGb3JtRGF0YSBkYXRhMiA9IG5ldyBGb3JtRGF0YSgpOwpkYXRhMi5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KGJ1dHRvbjEsNSk7CmRhdGEyLnJpZ2h0ID0gbmV3IEZvcm1BdHRhY2htZW50KDEwMCwtNSk7CmJ1dHRvbjIuc2V0TGF5b3V0RGF0YShkYXRhMik7CgpGb3JtRGF0YSBkYXRhMyA9IG5ldyBGb3JtRGF0YSg2MCw2MCk7CmRhdGEzLnRvcCA9IG5ldyBGb3JtQXR0YWNobWVudChidXR0b24xLDUpOwpkYXRhMy5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KDUwLC0zMCk7CmRhdGEzLnJpZ2h0ID0gbmV3IEZvcm1BdHRhY2htZW50KDUwLDMwKTsKYnV0dG9uMy5zZXRMYXlvdXREYXRhKGRhdGEzKTsKCkZvcm1EYXRhIGRhdGE0ID0gbmV3IEZvcm1EYXRhKCk7CmRhdGE0LnRvcCA9IG5ldyBGb3JtQXR0YWNobWVudChidXR0b24zLDUpOwpkYXRhNC5ib3R0b20gPSBuZXcgRm9ybUF0dGFjaG1lbnQoMTAwLC01KTsKZGF0YTQubGVmdCA9IG5ldyBGb3JtQXR0YWNobWVudCgyNSwwKTsKYnV0dG9uNC5zZXRMYXlvdXREYXRhKGRhdGE0KTsKCkZvcm1EYXRhIGRhdGE1ID0gbmV3IEZvcm1EYXRhKCk7CmRhdGE1LmJvdHRvbSA9IG5ldyBGb3JtQXR0YWNobWVudCgxMDAsLTUpOwpkYXRhNS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KGJ1dHRvbjQsNSk7CmJ1dHRvbjUuc2V0TGF5b3V0RGF0YShkYXRhNSk7PC9wcmU+Cgo8cD5JbiB0aGlzIGNhc2UsIHNpbmNlIG5vIHRvcCBhdHRhY2htZW50IHdhcyBkZWZpbmVkIGZvciA8Y29kZT5idXR0b24xPC9jb2RlPiBvcgo8Y29kZT5idXR0b24yPC9jb2RlPiwgdGhleSBhcmUgYXR0YWNoZWQgdG8gdGhlIHRvcCBvZiB0aGUgbGF5b3V0LiA8Y29kZT5idXR0b24zPC9jb2RlPiBpcyBjZW50cmVkCmluIHRoZSBsYXlvdXQgdXNpbmcgcGVyY2VudGFnZXMgYW5kIG9mZnNldHMgb24gdGhlIGxlZnQgYW5kIHJpZ2h0IHNpZGVzLgo8Y29kZT5idXR0b240PC9jb2RlPiBhbmQgPGNvZGU+YnV0dG9uNTwvY29kZT4gYXJlIGF0dGFjaGVkIHRvIHRoZSBib3R0b20gb2YgdGhlIGxheW91dCB3aXRoIGEgZml2ZQpwaXhlbCBvZmZzZXQuPC9wPgoKPGltZyBzcmM9ImltYWdlcy9Gb3JtTGF5b3V0U2FtcGxlNUJ1dHRvbnMwMS5qcGciIC8+Cgo8cD5XaGVuIHdlIHJlc2l6ZSwgdGhlIGF0dGFjaG1lbnRzIGJlY29tZSBtb3JlIHZpc2libGUuIDxjb2RlPmJ1dHRvbjE8L2NvZGU+IGlzCmF0dGFjaGVkIG9uIHRoZSBsZWZ0IGFuZCB0aGUgcmlnaHQgc2lkZSwgc28gd2hlbiB0aGUgd2luZG93IGlzIHJlc2l6ZWQsCml0IGdyb3dzLiBOb3RlIHRoYXQgdGhlIHJpZ2h0IHNpZGUgd2lsbCBhbHdheXMgYmUgYXQgMjUlIG9mIHRoZSB3aW5kb3cuoApUaGUgc2FtZSByZXNpemUgcmVzdWx0cyBhcHBseSBmb3IgPGNvZGU+YnV0dG9uMjwvY29kZT4sIGFzIGJvdGggc2lkZXMgYXJlIGF0dGFjaGVkLgpUaGUgbGVmdCBzaWRlIGlzIGF0dGFjaGVkIHRvIDxjb2RlPmJ1dHRvbjE8L2NvZGU+LCBzbyBpdCB3aWxsIGFsd2F5cyBiZSBhdCAyNSUgcGx1cyBmaXZlCnBpeGVscy4gPGNvZGU+YnV0dG9uMzwvY29kZT4gc3RheXMgaW4gdGhlIGNlbnRlciBvZiB0aGUgd2luZG93LCBob3Jpem9udGFsbHkuIDxjb2RlPmJ1dHRvbjQ8L2NvZGU+CmlzIGF0dGFjaGVkIGF0IHRoZSB0b3AgYW5kIHRoZSBib3R0b20sIHNvIGl0IGdyb3dzIHZlcnRpY2FsbHkgd2hlbiB0aGUKd2luZG93IGlzIHJlc2l6ZWQsIGJ1dCBpdCBpcyBvbmx5IGF0dGFjaGVkIG9uIHRoZSBsZWZ0IGFuZCBub3QgdGhlCnJpZ2h0LCBzbyBpdCBkb2VzIG5vdCBncm93IGhvcml6b250YWxseS4gPGNvZGU+YnV0dG9uNTwvY29kZT4gd2lsbCBub3QgZ3JvdyBvcgpzaHJpbmssIGJ1dCBpdCB3aWxsIGFsd2F5cyBzdGF5IGZpdmUgcGl4ZWxzIGF3YXkgZnJvbSA8Y29kZT5idXR0b240PC9jb2RlPiBvbiB0aGUgbGVmdCwKYW5kIGZpdmUgcGl4ZWxzIGF3YXkgZnJvbSB0aGUgYm90dG9tIG9mIHRoZSB3aW5kb3cuPC9wPgoKPGltZyBzcmM9ImltYWdlcy9Gb3JtTGF5b3V0U2FtcGxlNUJ1dHRvbnMwMVJlc2l6ZWQuanBnIiAvPgoKPGgzPkEgQ29tcGxleCBGb3JtTGF5b3V0IEV4YW1wbGU8L2gzPgoKPHA+VG8gaWxsdXN0cmF0ZSBob3cgPGNvZGU+Rm9ybUxheW91dDwvY29kZT4gY2FuIGJlIHVzZWQgZm9yIG1vcmUKY29tcGxpY2F0ZWQgYXJyYW5nZW1lbnRzLCB0aGUgRG9nIFNob3cgRW50cnkgZXhhbXBsZSBkb25lIHByZXZpb3VzbHkgZm9yCjxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+IGlzIHJlZG9uZSB1c2luZyA8Y29kZT5Gb3JtTGF5b3V0PC9jb2RlPi4gVGhpcwpjb2RlIHByb2R1Y2VzIGFuIGlkZW50aWNhbCBsYXlvdXQsIGJ1dCB1c2VzIGRpZmZlcmVudCBjb25jZXB0cyB0bwphY2hpZXZlIGl0LjwvcD4KCjxwcmU+aW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlBhaW50RXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlBhaW50TGlzdGVuZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkFkYXB0ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkV2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLkltYWdlOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5Gb3JtQXR0YWNobWVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuRm9ybURhdGE7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkZvcm1MYXlvdXQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5CdXR0b247CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5DYW52YXM7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Db21ibzsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkRpc3BsYXk7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5GaWxlRGlhbG9nOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuR3JvdXA7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5MYWJlbDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkxpc3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5TaGVsbDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLlRleHQ7CgpwdWJsaWMgY2xhc3MgRG9nU2hvd1JlZ2lzdHJhdGlvbldpbmRvd1dpdGhGb3JtTGF5b3V0IHsKCUltYWdlIGRvZ0ltYWdlOwoJVGV4dCBkb2dOYW1lVGV4dDsKCUNvbWJvIGRvZ0JyZWVkQ29tYm87CglDYW52YXMgZG9nUGhvdG87CglMaXN0IGNhdGVnb3JpZXM7CglUZXh0IG5hbWVUZXh0OwoJVGV4dCBwaG9uZVRleHQ7CgoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewoJCURpc3BsYXkgZGlzcGxheSA9IG5ldyBEaXNwbGF5KCk7CgkJU2hlbGwgc2hlbGwgPSBuZXcgRG9nU2hvd1JlZ2lzdHJhdGlvbldpbmRvdygpLmNyZWF0ZVNoZWxsKGRpc3BsYXkpOwoJCXNoZWxsLm9wZW4oKTsKCQl3aGlsZSAoIXNoZWxsLmlzRGlzcG9zZWQoKSkgewoJCQlpZiAoIWRpc3BsYXkucmVhZEFuZERpc3BhdGNoKCkpCgkJCQlkaXNwbGF5LnNsZWVwKCk7CgkJfQoJfQoJCglwdWJsaWMgU2hlbGwgY3JlYXRlU2hlbGwoZmluYWwgRGlzcGxheSBkaXNwbGF5KSB7CgkJZmluYWwgU2hlbGwgc2hlbGwgPSBuZXcgU2hlbGwoZGlzcGxheSk7CgkJRm9ybUxheW91dCBsYXlvdXQgPSBuZXcgRm9ybUxheW91dCgpOwoJCWxheW91dC5tYXJnaW5XaWR0aCA9IDU7CgkJbGF5b3V0Lm1hcmdpbkhlaWdodCA9IDU7CgkJc2hlbGwuc2V0TGF5b3V0KGxheW91dCk7CgkJc2hlbGwuc2V0VGV4dCgiRG9nIFNob3cgRW50cnkiKTsKCQkKCQlHcm91cCBvd25lckluZm8gPSBuZXcgR3JvdXAoc2hlbGwsIFNXVC5OT05FKTsKCQlvd25lckluZm8uc2V0VGV4dCgiT3duZXIgSW5mbyIpOwoJCUZvcm1MYXlvdXQgb3duZXJMYXlvdXQgPSBuZXcgRm9ybUxheW91dCgpOwoJCW93bmVyTGF5b3V0Lm1hcmdpbldpZHRoID0gNTsKCQlvd25lckxheW91dC5tYXJnaW5IZWlnaHQgPSA1OwoJCW93bmVySW5mby5zZXRMYXlvdXQob3duZXJMYXlvdXQpOwoJCQoJCUxhYmVsIGRvZ05hbWUgPSBuZXcgTGFiZWwoc2hlbGwsIFNXVC5OT05FKTsKCQlkb2dOYW1lLnNldFRleHQoIkRvZydzIE5hbWU6Iik7CgkJZG9nTmFtZVRleHQgPSBuZXcgVGV4dChzaGVsbCwgU1dULlNJTkdMRSB8IFNXVC5CT1JERVIpOwoJCQoJCUxhYmVsIGRvZ0JyZWVkID0gbmV3IExhYmVsKHNoZWxsLCBTV1QuTk9ORSk7CgkJZG9nQnJlZWQuc2V0VGV4dCgiQnJlZWQ6Iik7CgkJCgkJZG9nQnJlZWRDb21ibyA9IG5ldyBDb21ibyhzaGVsbCwgU1dULk5PTkUpOwoJCWRvZ0JyZWVkQ29tYm8uc2V0SXRlbXMobmV3IFN0cmluZ1tdIHsgIkNvbGxpZSIsICJQaXRidWxsIiwgIlBvb2RsZSIsCgkJCQkiU2NvdHRpZSIsICJCbGFjayBMYWIiIH0pOwoJCQoJCUxhYmVsIHBob3RvID0gbmV3IExhYmVsKHNoZWxsLCBTV1QuTk9ORSk7CgkJcGhvdG8uc2V0VGV4dCgiUGhvdG86Iik7CgkJZG9nUGhvdG8gPSBuZXcgQ2FudmFzKHNoZWxsLCBTV1QuQk9SREVSKTsKCQkKCQlCdXR0b24gYnJvd3NlID0gbmV3IEJ1dHRvbihzaGVsbCwgU1dULlBVU0gpOwoJCWJyb3dzZS5zZXRUZXh0KCJCcm93c2UuLi4iKTsKCQkKCQlCdXR0b24gZGVsZXRlID0gbmV3IEJ1dHRvbihzaGVsbCwgU1dULlBVU0gpOwoJCWRlbGV0ZS5zZXRUZXh0KCJEZWxldGUiKTsKCQkKCQlMYWJlbCBjYXRzID0gbmV3IExhYmVsKHNoZWxsLCBTV1QuTk9ORSk7CgkJY2F0cy5zZXRUZXh0KCJDYXRlZ29yaWVzIik7CgkJY2F0ZWdvcmllcyA9IG5ldyBMaXN0KHNoZWxsLCBTV1QuTVVMVEkgfCBTV1QuQk9SREVSIHwgU1dULlZfU0NST0xMCgkJCQl8IFNXVC5IX1NDUk9MTCk7CgkJY2F0ZWdvcmllcy5zZXRJdGVtcyhuZXcgU3RyaW5nW10geyAiQmVzdCBvZiBCcmVlZCIsICJQcmV0dGllc3QgRmVtYWxlIiwKCQkJCSJIYW5kc29tZXN0IE1hbGUiLCAiQmVzdCBEcmVzc2VkIiwgIkZsdWZmaWVzdCBFYXJzIiwKCQkJCSJNb3N0IENvbG9ycyIsICJCZXN0IFBlcmZvcm1lciIsICJMb3VkZXN0IEJhcmsiLAoJCQkJIkJlc3QgQmVoYXZlZCIsICJQcmV0dGllc3QgRXllcyIsICJNb3N0IEhhaXIiLCAiTG9uZ2VzdCBUYWlsIiwKCQkJCSJDdXRlc3QgVHJpY2siIH0pOwoJCQoJCUJ1dHRvbiBlbnRlciA9IG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKTsKCQllbnRlci5zZXRUZXh0KCJFbnRlciIpOwoJCUZvcm1EYXRhIGRhdGEgPSBuZXcgRm9ybURhdGEoKTsKCQlkYXRhLnRvcCA9IG5ldyBGb3JtQXR0YWNobWVudChkb2dOYW1lVGV4dCwgMCwgU1dULkNFTlRFUik7CgkJZG9nTmFtZS5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCWRhdGEgPSBuZXcgRm9ybURhdGEoKTsKCQlkYXRhLmxlZnQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoZG9nTmFtZSwgNSk7CgkJZGF0YS5yaWdodCA9IG5ldyBGb3JtQXR0YWNobWVudCgxMDAsIDApOwoJCWRvZ05hbWVUZXh0LnNldExheW91dERhdGEoZGF0YSk7CgkJCgkJZGF0YSA9IG5ldyBGb3JtRGF0YSgpOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KGRvZ0JyZWVkQ29tYm8sIDAsIFNXVC5DRU5URVIpOwoJCWRvZ0JyZWVkLnNldExheW91dERhdGEoZGF0YSk7CgkJZGF0YSA9IG5ldyBGb3JtRGF0YSgpOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KGRvZ05hbWVUZXh0LCA1KTsKCQlkYXRhLmxlZnQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoZG9nTmFtZVRleHQsIDAsIFNXVC5MRUZUKTsKCQlkYXRhLnJpZ2h0ID0gbmV3IEZvcm1BdHRhY2htZW50KGNhdGVnb3JpZXMsIC01KTsKCQlkb2dCcmVlZENvbWJvLnNldExheW91dERhdGEoZGF0YSk7CgkJCgkJZGF0YSA9IG5ldyBGb3JtRGF0YSg4MCwgODApOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KGRvZ0JyZWVkQ29tYm8sIDUpOwoJCWRhdGEubGVmdCA9IG5ldyBGb3JtQXR0YWNobWVudChkb2dOYW1lVGV4dCwgMCwgU1dULkxFRlQpOwoJCWRhdGEucmlnaHQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoY2F0ZWdvcmllcywgLTUpOwoJCWRhdGEuYm90dG9tID0gbmV3IEZvcm1BdHRhY2htZW50KG93bmVySW5mbywgLTUpOwoJCWRvZ1Bob3RvLnNldExheW91dERhdGEoZGF0YSk7CgkJZG9nUGhvdG8uYWRkUGFpbnRMaXN0ZW5lcihuZXcgUGFpbnRMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgcGFpbnRDb250cm9sKGZpbmFsIFBhaW50RXZlbnQgZXZlbnQpIHsKCQkJCWlmIChkb2dJbWFnZSAhPSBudWxsKSB7CgkJCQkJZXZlbnQuZ2MuZHJhd0ltYWdlKGRvZ0ltYWdlLCAwLCAwKTsKCQkJCX0KCQkJfQoJCX0pOwoJCWRhdGEgPSBuZXcgRm9ybURhdGEoKTsKCQlkYXRhLnRvcCA9IG5ldyBGb3JtQXR0YWNobWVudChkb2dQaG90bywgMCwgU1dULlRPUCk7CgkJcGhvdG8uc2V0TGF5b3V0RGF0YShkYXRhKTsKCQlkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgkJZGF0YS50b3AgPSBuZXcgRm9ybUF0dGFjaG1lbnQocGhvdG8sIDUpOwoJCWRhdGEucmlnaHQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoZG9nUGhvdG8sIC01KTsKCQlicm93c2Uuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQlicm93c2UuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGV2ZW50KSB7CgkJCQlTdHJpbmcgZmlsZU5hbWUgPSBuZXcgRmlsZURpYWxvZyhzaGVsbCkub3BlbigpOwoJCQkJaWYgKGZpbGVOYW1lICE9IG51bGwpIHsKCQkJCQlkb2dJbWFnZSA9IG5ldyBJbWFnZShkaXNwbGF5LCBmaWxlTmFtZSk7CgkJCQl9CgkJCX0KCQl9KTsKCQkKCQlkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgkJZGF0YS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KGJyb3dzZSwgMCwgU1dULkxFRlQpOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KGJyb3dzZSwgNSk7CgkJZGF0YS5yaWdodCA9IG5ldyBGb3JtQXR0YWNobWVudChkb2dQaG90bywgLTUpOwoJCWRlbGV0ZS5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCWRlbGV0ZS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZXZlbnQpIHsKCQkJCWlmIChkb2dJbWFnZSAhPSBudWxsKSB7CgkJCQkJZG9nSW1hZ2UuZGlzcG9zZSgpOwoJCQkJCWRvZ0ltYWdlID0gbnVsbDsKCQkJCQlkb2dQaG90by5yZWRyYXcoKTsKCQkJCX0KCQkJfQoJCX0pOwoJCQoJCWRhdGEgPSBuZXcgRm9ybURhdGEoOTAsIDE0MCk7CgkJZGF0YS50b3AgPSBuZXcgRm9ybUF0dGFjaG1lbnQoZG9nUGhvdG8sIDAsIFNXVC5UT1ApOwoJCWRhdGEucmlnaHQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoMTAwLCAwKTsKCQlkYXRhLmJvdHRvbSA9IG5ldyBGb3JtQXR0YWNobWVudChlbnRlciwgLTUpOwoJCWNhdGVnb3JpZXMuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkKCQlkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgkJZGF0YS5ib3R0b20gPSBuZXcgRm9ybUF0dGFjaG1lbnQoY2F0ZWdvcmllcywgLTUpOwoJCWRhdGEubGVmdCA9IG5ldyBGb3JtQXR0YWNobWVudChjYXRlZ29yaWVzLCAwLCBTV1QuQ0VOVEVSKTsKCQljYXRzLnNldExheW91dERhdGEoZGF0YSk7CgkJCgkJZGF0YSA9IG5ldyBGb3JtRGF0YSgpOwoJCWRhdGEucmlnaHQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoMTAwLCAwKTsKCQlkYXRhLmJvdHRvbSA9IG5ldyBGb3JtQXR0YWNobWVudCgxMDAsIDApOwoJCWVudGVyLnNldExheW91dERhdGEoZGF0YSk7CgkJZW50ZXIuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGV2ZW50KSB7CgkJCQlTeXN0ZW0ub3V0LnByaW50bG4oIlxuRG9nIE5hbWU6ICIgKyBkb2dOYW1lVGV4dC5nZXRUZXh0KCkpOwoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJEb2cgQnJlZWQ6ICIgKyBkb2dCcmVlZENvbWJvLmdldFRleHQoKSk7CgkJCQlTeXN0ZW0ub3V0LnByaW50bG4oIk93bmVyIE5hbWU6ICIgKyBuYW1lVGV4dC5nZXRUZXh0KCkpOwoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJPd25lciBQaG9uZTogIiArIHBob25lVGV4dC5nZXRUZXh0KCkpOwoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJDYXRlZ29yaWVzOiIpOwoJCQkJU3RyaW5nIGNhdHNbXSA9IGNhdGVnb3JpZXMuZ2V0U2VsZWN0aW9uKCk7CgkJCQlmb3IgKGludCBpID0gMDsgaSA8IGNhdHMubGVuZ3RoOyBpKyspIHsKCQkJCQlTeXN0ZW0ub3V0LnByaW50bG4oIlx0IiArIGNhdHNbaV0pOwoJCQkJfQoJCQl9CgkJfSk7CgkJCgkJZGF0YSA9IG5ldyBGb3JtRGF0YSgpOwoJCWRhdGEuYm90dG9tID0gbmV3IEZvcm1BdHRhY2htZW50KGVudGVyLCAtNSk7CgkJZGF0YS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KDAsIDApOwoJCWRhdGEucmlnaHQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoY2F0ZWdvcmllcywgLTUpOwoJCW93bmVySW5mby5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCQoJCUxhYmVsIG5hbWUgPSBuZXcgTGFiZWwob3duZXJJbmZvLCBTV1QuTlVMTCk7CgkJbmFtZS5zZXRUZXh0KCJOYW1lOiIpOwoJCQoJCUxhYmVsIHBob25lID0gbmV3IExhYmVsKG93bmVySW5mbywgU1dULlBVU0gpOwoJCXBob25lLnNldFRleHQoIlBob25lOiIpOwoJCQoJCW5hbWVUZXh0ID0gbmV3IFRleHQob3duZXJJbmZvLCBTV1QuU0lOR0xFIHwgU1dULkJPUkRFUik7CgkJcGhvbmVUZXh0ID0gbmV3IFRleHQob3duZXJJbmZvLCBTV1QuU0lOR0xFIHwgU1dULkJPUkRFUik7CgkJCgkJZGF0YSA9IG5ldyBGb3JtRGF0YSgpOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KG5hbWVUZXh0LCAwLCBTV1QuQ0VOVEVSKTsKCQluYW1lLnNldExheW91dERhdGEoZGF0YSk7CgkJCgkJZGF0YSA9IG5ldyBGb3JtRGF0YSgpOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KHBob25lVGV4dCwgMCwgU1dULkNFTlRFUik7CgkJcGhvbmUuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkKCQlkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgkJZGF0YS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KHBob25lLCA1KTsKCQlkYXRhLnJpZ2h0ID0gbmV3IEZvcm1BdHRhY2htZW50KDEwMCwgMCk7CgkJbmFtZVRleHQuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkKCQlkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgkJZGF0YS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KG5hbWVUZXh0LCAwLCBTV1QuTEVGVCk7CgkJZGF0YS5yaWdodCA9IG5ldyBGb3JtQXR0YWNobWVudCgxMDAsIDApOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KDU1LCAwKTsKCQlwaG9uZVRleHQuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkKCQlzaGVsbC5wYWNrKCk7CgkJCgkJcmV0dXJuIHNoZWxsOwoJfQkKfTwvcHJlPgoKPHA+VGhpcyBpcyB3aGF0IHRoZSBsYXlvdXQgbG9va3MgbGlrZSBhZnRlciBNYXJ5IFNtaXRoIGVudGVycwpCaWZmb3JkIGluIHRoZSBkb2cgc2hvdzo8L3A+Cgo8aW1nIHNyYz0iaW1hZ2VzL0RvZ1Nob3dCaWZmV2l0aEZvcm1MYXlvdXQuanBnIiAvPgoKPC9wPgo8cD5XaGVuIHRoZSB3aW5kb3cgaXMgcmVzaXplZCwgdGhlIHNhbWUgY29udHJvbHMgYXJlIHJlc2l6ZWQgYXMgaW4KdGhlIDxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+IGV4YW1wbGUuPC9wPgoKPGltZyBzcmM9ImltYWdlcy9Eb2dTaG93QmlmZldpdGhGb3JtTGF5b3V0UmVzaXplZC5qcGciIC8+Cgo8aDI+V3JpdGluZyBZb3VyIE93biBMYXlvdXQgQ2xhc3M8L2gyPgoKPHA+T2NjYXNpb25hbGx5LCB5b3UgbWF5IHdhbnQgdG8gd3JpdGUgeW91ciBvd24gPGNvZGU+TGF5b3V0PC9jb2RlPgpjbGFzcy4gUGVyaGFwcyB5b3VyIGxheW91dCBuZWVkcyBhcmUgdmVyeSBjb21wbGV4LiBNYXliZSB5b3UgaGF2ZSB0aGUKc2FtZSBsb29rIGluIG1hbnkgcGxhY2VzLCBhbmQgeW91IHdhbnQgdG8gdGFrZSBhZHZhbnRhZ2Ugb2YgY29kZSByZXVzZS4KT3IgeW91IHdhbnQgdG8gbGV2ZXJhZ2UgZG9tYWluIGtub3dsZWRnZSB0byBjcmVhdGUgYSB2ZXJ5IGVmZmljaWVudApsYXlvdXQgY2xhc3MuIFdoYXRldmVyIHRoZSByZWFzb24sIHRoZXJlIGFyZSB0aGluZ3MgdG8gY29uc2lkZXIgYmVmb3JlCndyaXRpbmcgYSBuZXcgY2xhc3M6PC9wPgoKPHVsPgoJPGxpPkNhbiB0aGUgbGF5b3V0IGJlIGRvbmUgdXNpbmcgYSA8Y29kZT5HcmlkTGF5b3V0PC9jb2RlPiBvciA8Y29kZT5Gb3JtTGF5b3V0PC9jb2RlPiwKCXdpdGggbWF5YmUgYSBmZXcgbmVzdGVkIGxheW91dHM/PC9saT4KCTxsaT5DYW4gdGhlIGRlc2lyZWQgZWZmZWN0IGJlIG1vcmUgZWFzaWx5IGFjaGlldmVkIHdpdGggYSByZXNpemUKCWxpc3RlbmVyPzwvbGk+Cgk8bGk+QXJlIHlvdSBkZWZpbmluZyBhIGdlbmVyYWwgbGF5b3V0IGFsZ29yaXRobSBvciBqdXN0Cglwb3NpdGlvbmluZyB3aWRnZXRzPzwvbGk+CjwvdWw+Cgo8cD5Vbmxlc3MgeW91IGFyZSB3cml0aW5nIGEgdmVyeSBnZW5lcmljIDxjb2RlPkxheW91dDwvY29kZT4gdHlwZQp0aGF0IHdpbGwgYmUgdXNlZCBieSBzZXZlcmFsIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4gd2lkZ2V0cywgaXQgaXMgb2Z0ZW4KYmV0dGVyIGFuZCBlYXNpZXIgdG8gc2ltcGx5IGNhbGN1bGF0ZSBzaXplcyBhbmQgcG9zaXRpb24gY2hpbGRyZW4gaW4gYQpyZXNpemUgbGlzdGVuZXIuIE1hbnkgb2YgdGhlIFNXVCBjdXN0b20gd2lkZ2V0cyB3ZXJlIHdyaXR0ZW4gdGhpcyB3YXkuCkFsdGhvdWdoIGEgbmV3IHdpZGdldCBjYW4gYmUgaW1wbGVtZW50ZWQgYXMgYSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+Lzxjb2RlPkxheW91dDwvY29kZT4KcGFpciwgaW1wbGVtZW50aW5nIGl0IGFzIGEgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiB0aGF0IGRvZXMgaXRzIGxheW91dAppbiBhIHJlc2l6ZSBsaXN0ZW5lciBhbmQgY29tcHV0ZXMgaXRzIHByZWZlcnJlZCBzaXplIGluIDxjb2RlPmNvbXB1dGVTaXplPC9jb2RlPgppcyBjbGVhcmVyLCBhbmQgZG9lcyBub3QgaW52b2x2ZSB3cml0aW5nIGFuIGV4dHJhIGNsYXNzLjwvcD4KCjxwPkZpcnN0LCB3ZSB3aWxsIGxvb2sgYXQgaG93IGxheW91dHMgd29yaywgYW5kIHRoZW4gd2Ugd2lsbCBjcmVhdGUKYSBuZXcgPGNvZGU+TGF5b3V0PC9jb2RlPiBjbGFzcy4gQW5vdGhlciBleGFtcGxlIG9mIHdyaXRpbmcgeW91ciBvd24gPGNvZGU+TGF5b3V0PC9jb2RlPgpjYW4gYmUgZm91bmQgaW4gdGhlIDxpPkNvbXBvdW5kIFdpZGdldCBFeGFtcGxlPC9pPiBzZWN0aW9uIG9mIDxhCglocmVmPSJodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2FydGljbGVzL0FydGljbGUtV3JpdGluZyUyMFlvdXIlMjBPd24lMjBXaWRnZXQvV3JpdGluZyUyMFlvdXIlMjBPd24lMjBXaWRnZXQuaHRtIj5DcmVhdGluZwpZb3VyIE93biBXaWRnZXRzIFVzaW5nIFNXVDwvYT4sIHdoaWNoIHNob3dzIGhvdyB0byBhY2hpZXZlIHRoZSBzYW1lIGxvb2sKdXNpbmcgZWl0aGVyIGEgcmVzaXplIGxpc3RlbmVyIG9yIGEgbmV3IDxjb2RlPkxheW91dDwvY29kZT4gY2xhc3MuPC9wPgoKPGgzPkhvdyBMYXlvdXRzIFdvcms8L2gzPgoKPHA+PGNvZGU+TGF5b3V0PC9jb2RlPiBpcyB0aGUgYWJzdHJhY3Qgc3VwZXJjbGFzcyBvZiBhbGwgbGF5b3V0cy4gSXQKb25seSBoYXMgdHdvIG1ldGhvZHM6IDxjb2RlPmNvbXB1dGVTaXplPC9jb2RlPiBhbmQgPGNvZGU+bGF5b3V0PC9jb2RlPi4KVGhlIGNsYXNzIGlzIGRlZmluZWQgYXMgZm9sbG93czo8L3A+Cgo8cHJlPnB1YmxpYyBhYnN0cmFjdCBjbGFzcyBMYXlvdXQgewogICAgcHJvdGVjdGVkIGFic3RyYWN0IFBvaW50IGNvbXB1dGVTaXplKENvbXBvc2l0ZSBjb21wb3NpdGUsIGludCB3aWR0aEhpbnQsIGludCBoZWlnaHRIaW50LCBib29sZWFuIGZsdXNoQ2FjaGUpOwogICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgbGF5b3V0KENvbXBvc2l0ZSBjb21wb3NpdGUsIGJvb2xlYW4gZmx1c2hDYWNoZSk7Cn08L3ByZT4KCjxwPlRoZSA8Y29kZT5jb21wdXRlU2l6ZTwvY29kZT4gbWV0aG9kIGNhbGN1bGF0ZXMgdGhlIHdpZHRoIGFuZApoZWlnaHQgb2YgYSByZWN0YW5nbGUgdGhhdCBlbmNsb3NlcyBhbGwgb2YgdGhlIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4ncwpjaGlsZHJlbiBvbmNlIHRoZXkgaGF2ZSBiZWVuIHNpemVkIGFuZCBwbGFjZWQgYWNjb3JkaW5nIHRvIHRoZSBsYXlvdXQKYWxnb3JpdGhtIGVuY29kZWQgaW4gdGhlIDxjb2RlPkxheW91dDwvY29kZT4gY2xhc3MuIFRoZSBoaW50IHBhcmFtZXRlcnMKYWxsb3cgdGhlIHdpZHRoIGFuZC9vciBoZWlnaHQgdG8gYmUgY29uc3RyYWluZWQuIEZvciBleGFtcGxlLCBhIGxheW91dAptYXkgY2hvb3NlIHRvIGdyb3cgaW4gb25lIGRpbWVuc2lvbiBpZiBjb25zdHJhaW5lZCBpbiBhbm90aGVyLiBBIGhpbnQgb2YKU1dULkRFRkFVTFQgbWVhbnMgdG8gdXNlIHRoZSBwcmVmZXJyZWQgc2l6ZS48L3A+Cgo8cD5UaGUgPGNvZGU+bGF5b3V0PC9jb2RlPiBtZXRob2QgcG9zaXRpb25zIGFuZCBzaXplcyB0aGUgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPidzCmNoaWxkcmVuLiBBIDxjb2RlPkxheW91dDwvY29kZT4gY2FuIGNob29zZSB0byBjYWNoZSBsYXlvdXQtcmVsYXRlZAppbmZvcm1hdGlvbiwgc3VjaCBhcyB0aGUgcHJlZmVycmVkIGV4dGVudCBvZiBlYWNoIG9mIHRoZSBjaGlsZHJlbi4gVGhlIDxjb2RlPmZsdXNoQ2FjaGU8L2NvZGU+CnBhcmFtZXRlciB0ZWxscyB0aGUgPGNvZGU+TGF5b3V0PC9jb2RlPiB0byBmbHVzaCBjYWNoZWQgZGF0YS48L3A+Cgo8cD5TaW5jZSBhIDxjb2RlPkxheW91dDwvY29kZT4gY29udHJvbHMgdGhlIHNpemUgYW5kIHBsYWNlbWVudCBvZgp3aWRnZXRzIGluIGEgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiwgdGhlcmUgYXJlIHNldmVyYWwgbWV0aG9kcyBpbiA8Y29kZT5Db21wb3NpdGU8L2NvZGU+CnRoYXQgYXJlIHVzZWQgd2l0aCA8Y29kZT5MYXlvdXQ8L2NvZGU+cy48L3A+Cgo8cD5UaGUgZmlyc3QgdHdvIG1ldGhvZHMgYWxsb3cgc2V0dGluZyBhbmQgZ2V0dGluZyBhIDxjb2RlPkxheW91dDwvY29kZT4Kb2JqZWN0IGluIGEgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPi48L3A+Cgo8cHJlPnB1YmxpYyB2b2lkIHNldExheW91dChMYXlvdXQgbGF5b3V0KTsKcHVibGljIExheW91dCBnZXRMYXlvdXQoKTs8L3ByZT4KCjxwPkFuIGFwcGxpY2F0aW9uIGNhbiBmb3JjZSBhIDxjb2RlPkxheW91dDwvY29kZT4gdG8gcmVjYWxjdWxhdGUgdGhlCnNpemVzIG9mIGFuZCByZXBvc2l0aW9uIGNoaWxkcmVuIGJ5IHNlbmRpbmcgPGNvZGU+bGF5b3V0KCk8L2NvZGU+IHRvIHRoZQpwYXJlbnQgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPi48L3A+Cgo8cHJlPnB1YmxpYyB2b2lkIGxheW91dChib29sZWFuIGNoYW5nZWQpOw0KcHVibGljIHZvaWQgbGF5b3V0KCk7CiAgICAvLyBjYWxscyBsYXlvdXQodHJ1ZSk7PC9wcmU+Cgo8cD5Zb3Ugd291bGQgZG8gdGhpcyBhZnRlciBjaGFuZ2luZyBhbnl0aGluZyBhYm91dCB0aGUgY2hpbGRyZW4gdGhhdAptaWdodCBhZmZlY3QgdGhlaXIgc2l6ZSBvciBwb3NpdGlvbiwgc3VjaCBhcyBjaGFuZ2luZyB0aGUgZm9udCBvZiBhCmNoaWxkLCBjaGFuZ2luZyB0aGUgdGV4dCBvciBpbWFnZSBvZiBhIGNoaWxkLCBhZGRpbmcgYSBuZXcgY2hpbGQsIG9yCmFkZGluZyBjaGlsZHJlbiB0byBhIGNoaWxkIChJZiB0aGUgY2hpbGQgY2FuIGFjY29tbW9kYXRlIHRoZSBjaGFuZ2UsCnRoZW4gbGF5b3V0IG1heSBub3QgYmUgbmVjZXNzYXJ5IJYgZm9yIGV4YW1wbGUsIGNoYW5naW5nIHRoZSBmb250IG9yCnRleHQgb2YgYSBzY3JvbGxhYmxlIG11bHRpLWxpbmUgPGNvZGU+VGV4dDwvY29kZT4pLiBTaW5jZSB0aGVzZSBjaGFuZ2VzCmFyZSBkb25lIHByb2dyYW1tYXRpY2FsbHksIHRoZXkgZG8gbm90IGNhdXNlIGV2ZW50cyB0byBoYXBwZW4uCkNvbnNlcXVlbnRseSwgdGhlIHBhcmVudCBkb2Vzbid0IGtub3cgYWJvdXQgdGhlIGNoYW5nZXMsIGFuZCBoYXMgdG8gYmUKdG9sZCB0aHJvdWdoIHRoZSA8Y29kZT5sYXlvdXQ8L2NvZGU+IG1ldGhvZC4gVGhpcyBzdHJhdGVneSByZWR1Y2VzIGZsYXNoCmJlY2F1c2UgdGhlIGFwcGxpY2F0aW9uIGNhbiBtYWtlIHNldmVyYWwgY2hhbmdlcyBhbmQgdGhlbiB0ZWxsIHRoZQpwYXJlbnQgdG8gbGF5b3V0LCBhbmQgdGhlIGNoaWxkcmVuIGFyZSBvbmx5IHJlZHJhd24gb25jZSBpbnN0ZWFkIG9mIG9uY2UKcGVyIGNoYW5nZS4gSWYgPGNvZGU+bGF5b3V0KCk8L2NvZGU+IGlzIG5vdCBjYWxsZWQgYW5kIGNoYW5nZXMgYXJlIG1hZGUKYWZ0ZXIgdGhlIHNoZWxsIGlzIG9wZW5lZCwgdGhlbiB0aGUgY2hpbGRyZW4gbWF5IG5vdCBiZSBjb3JyZWN0bHkgbGFpZApvdXQgdW50aWwgdGhlIHNoZWxsIGlzIHNvbWVob3cgcmVzaXplZC4gTm90ZSB0aGF0IDxjb2RlPnNoZWxsLm9wZW4oKTwvY29kZT4KY2F1c2VzIGEgbGF5b3V0IHRvIG9jY3VyLjwvcD4KCjxwPlRoZSA8Y29kZT5jb21wdXRlU2l6ZTwvY29kZT4gbWV0aG9kcyBvZiBhIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4KY2FsY3VsYXRlIHRoZSBDb21wb3NpdGUncyBwcmVmZXJyZWQgc2l6ZSwgd2hpY2ggaXMgdGhlIHNpemUgb2YgaXRzCmNsaWVudCBhcmVhIGFzIGRldGVybWluZWQgYnkgdGhlIDxjb2RlPkxheW91dDwvY29kZT4sIHBsdXMgaXRzIHRyaW0uPC9wPgoKPHByZT5wdWJsaWMgUG9pbnQgY29tcHV0ZVNpemUoaW50IHdpZHRoSGludCwgaW50IGhlaWdodEhpbnQsIGJvb2xlYW4gY2hhbmdlZCk7CnB1YmxpYyBQb2ludCBjb21wdXRlU2l6ZShpbnQgd2lkdGhIaW50LCBpbnQgaGVpZ2h0SGludCk7CiAgICAvLyBjYWxscyBjb21wdXRlU2l6ZSh3aWR0aEhpbnQsIGhlaWdodEhpbnQsIHRydWUpOzwvcHJlPgoKPHA+VGhlIDxiPmNsaWVudEFyZWE8L2I+IG9mIGEgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiBpcyB0aGUKcmVjdGFuZ2xlIHRoYXQgd2lsbCBjb250YWluIGFsbCBvZiB0aGUgY2hpbGRyZW4uIEEgPGNvZGU+TGF5b3V0PC9jb2RlPgpwb3NpdGlvbnMgdGhlIGNoaWxkcmVuIGluc2lkZSB0aGUgY2xpZW50IGFyZWEuPC9wPgoKPHByZT5wdWJsaWMgUmVjdGFuZ2xlIGdldENsaWVudEFyZWEgKCk7PC9wcmU+Cgo8cD5UaGUgPGI+dHJpbTwvYj4gb2YgYSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IGlzIHRoZSBhcmVhIG91dHNpZGUKdGhlIGNsaWVudCBhcmVhLiBGb3Igc29tZSBjb21wb3NpdGVzLCB0aGUgc2l6ZSBvZiB0aGUgdHJpbSBpcyB6ZXJvLiBUaGUKdHJpbSBjYW4gYmUgY29tcHV0ZWQgYnkgcGFzc2luZyB0aGUgZGltZW5zaW9ucyBvZiB0aGUgY2xpZW50IGFyZWEgaW50bwp0aGUgbWV0aG9kIDxjb2RlPmNvbXB1dGVUcmltPC9jb2RlPi48L3A+Cgo8cHJlPnB1YmxpYyBSZWN0YW5nbGUgY29tcHV0ZVRyaW0gKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KTs8L3ByZT4KCjxwPlNlbmRpbmcgPGNvZGU+cGFjazwvY29kZT4gdG8gYSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IHJlc2l6ZXMgaXQKdG8gaXRzIHByZWZlcnJlZCBzaXplLjwvcD4KCjxwcmU+cHVibGljIHZvaWQgcGFjayhib29sZWFuIGNoYW5nZWQpOwogICAgLy8gY2FsbHMgc2V0U2l6ZShjb21wdXRlU2l6ZShTV1QuREVGQVVMVCwgU1dULkRFRkFVTFQsIGNoYW5nZWQpKTsKcHVibGljIHZvaWQgcGFjaygpOwogICAgLy8gY2FsbHMgcGFjayh0cnVlKTs8L3ByZT4KCjxwPlRoZSBib29sZWFuIHBhcmFtZXRlciB0byB0aGUgPGNvZGU+bGF5b3V0PC9jb2RlPiwgPGNvZGU+Y29tcHV0ZVNpemU8L2NvZGU+LAphbmQgPGNvZGU+cGFjazwvY29kZT4gbWV0aG9kcyBpcyB0aGUgPGNvZGU+Y2hhbmdlZDwvY29kZT4gZmxhZy4gSWYgPGNvZGU+dHJ1ZTwvY29kZT4sCml0IGluZGljYXRlcyB0aGF0IHRoZSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+J3MgY29udGVudHMgaGF2ZSBjaGFuZ2VkIGluCnNvbWUgd2F5IHRoYXQgYWZmZWN0cyBpdHMgcHJlZmVycmVkIHNpemUsIHRoZXJlZm9yZSBhbnkgY2FjaGVzIHRoYXQgdGhlCjxjb2RlPkxheW91dDwvY29kZT4gbWF5IGhhdmUgYmVlbiBrZWVwaW5nIG5lZWQgdG8gYmUgZmx1c2hlZC4gV2hlbiBhIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4KaXMgcmVzaXplZCwgaXQgYXNrcyBpdHMgPGNvZGU+TGF5b3V0PC9jb2RlPiB0byBsYXkgb3V0IGl0cyBjaGlsZHJlbiBieQpjYWxsaW5nIGxheW91dChmYWxzZSk7IHRoZXJlZm9yZSB3aWRnZXQgY29udGVudCBjYWNoZXMgYXJlIDxpPm5vdDwvaT4KZmx1c2hlZC4gVGhpcyBsZXRzIHRoZSA8Y29kZT5MYXlvdXQ8L2NvZGU+IHBlcmZvcm0gYW55IGV4cGVuc2l2ZQpjYWxjdWxhdGlvbnMgb25seSB3aGVuIG5lY2Vzc2FyeS48L3A+Cgo8cD5DYWNoaW5nIGNhbiBpbmNyZWFzZSBwZXJmb3JtYW5jZSwgYnV0IGl0IGNhbiBhbHNvIGJlIHRyaWNreS4gWW91CmNhbiBjaG9vc2Ugbm90IHRvIGNhY2hlIGF0IGFsbDogaW4gZmFjdCwgaXQgaXMgYmVzdCBub3QgdG8gdHJ5IGNhY2hpbmcKdW50aWwgeW91ciBjb2RlIGlzIHN0YWJsZS4gV2hlbiBjb25zaWRlcmluZyB3aGF0IHRvIGNhY2hlLCBiZSBjZXJ0YWluCm5vdCB0byBzdG9yZSBhbnkgd2lkZ2V0IHN0YXRlLCBzdWNoIGFzIHRoZSB0ZXh0IG9mIGEgbGFiZWwsIG9yIHRoZQpudW1iZXIgb2YgaXRlbXMgaW4gYSBsaXN0LjwvcD4KCjxoMz5DdXN0b20gTGF5b3V0IEV4YW1wbGU8L2gzPgoKPHA+SWYgeW91IGhhdmUgc2V2ZXJhbCB2ZXJ0aWNhbGx5IG9yaWVudGVkIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4Kd2lkZ2V0cyBpbiB5b3VyIGFwcGxpY2F0aW9uLCB5b3UgbWlnaHQgY2hvb3NlIHRvIHdyaXRlIDxjb2RlPkNvbHVtbkxheW91dDwvY29kZT4uCldlIHdpbGwgc2hvdyBhIHNpbXBsZSB2ZXJzaW9uIG9mIGEgPGNvZGU+TGF5b3V0PC9jb2RlPiBjbGFzcyB0aGF0IGxheXMKb3V0IDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4gY2hpbGRyZW4gaW50byBhIHNpbmdsZSBjb2x1bW4uIFRoZSBjbGFzcyBoYXMKZml4ZWQgbWFyZ2lucyBhbmQgc3BhY2luZy4gQ2hpbGRyZW4gYXJlIGdpdmVuIHRoZSBzYW1lIHdpZHRoLCBidXQgdGhleQp0YWtlIHRoZWlyIG5hdHVyYWwgaGVpZ2h0LiAoTm90ZSB0aGF0IDxjb2RlPlJvd0xheW91dDwvY29kZT4gd2lsbCBoYXZlIDxjb2RlPkNvbHVtbkxheW91dDwvY29kZT4KYmVoYXZpb3VyIGlmIGl0cyB0eXBlIGlzIHNldCB0byA8Y29kZT5TV1QuVkVSVElDQUw8L2NvZGU+LiBUaGlzIGV4YW1wbGUgaXMsCnRoZXJlZm9yZSwganVzdCBhbiBleGFtcGxlLiBJbiBwcmFjdGljZSwgaWYgeW91IG5lZWQgdG8gbGF5IHdpZGdldHMgb3V0CmluIGEgY29sdW1uLCB5b3Ugd291bGQgdXNlIDxjb2RlPlJvd0xheW91dC48L2NvZGU+KTwvcD4KCjxwPlRoZSBjb2RlIGZvciB0aGUgPGNvZGU+Q29sdW1uTGF5b3V0PC9jb2RlPiBjbGFzcyBpcyBiZWxvdy4gTm90ZQp0aGF0IHdlIGNhY2hlIHRoZSB3aWR0aCBvZiB0aGUgd2lkZXN0IGNoaWxkLCBhbmQgdGhlIHN1bSBvZiB0aGUgY2hpbGQKaGVpZ2h0cyAocGx1cyBzcGFjaW5nKSwgYW5kIHRoZXNlIHZhbHVlcyBhcmUgdXNlZCB0byBjb21wdXRlIHRoZSBzaXplCmFuZCBsaWUgb3V0IHRoZSBjaGlsZHJlbi4gVGhleSBhcmUgcmVjYWxjdWxhdGVkIGlmIDxjb2RlPmZsdXNoQ2FjaGU8L2NvZGU+CmlzIDxjb2RlPnRydWU8L2NvZGU+LjwvcD4KCjxwcmU+aW1wb3J0IG9yZy5lY2xpcHNlLnN3dC4qOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLio7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy4qOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC4qOwoKcHVibGljIGNsYXNzIENvbHVtbkxheW91dCBleHRlbmRzIExheW91dCB7CiAgICAvLyBmaXhlZCBtYXJnaW4gYW5kIHNwYWNpbmcKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BUkdJTiA9IDQ7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTUEFDSU5HID0gMjsKICAgIC8vIGNhY2hlCiAgICBQb2ludFtdIHNpemVzOwogICAgaW50IG1heFdpZHRoLCB0b3RhbEhlaWdodDsKCiAgICBwcm90ZWN0ZWQgUG9pbnQgY29tcHV0ZVNpemUoQ29tcG9zaXRlIGNvbXBvc2l0ZSwgaW50IHdIaW50LCBpbnQgaEhpbnQsCiAgICAgICAgICAgIGJvb2xlYW4gZmx1c2hDYWNoZSkgewogICAgICAgIENvbnRyb2wgY2hpbGRyZW5bXSA9IGNvbXBvc2l0ZS5nZXRDaGlsZHJlbigpOwogICAgICAgIGlmIChmbHVzaENhY2hlIHx8IHNpemVzID09IG51bGwgfHwgc2l6ZXMubGVuZ3RoICE9IGNoaWxkcmVuLmxlbmd0aCkgewogICAgICAgICAgICBpbml0aWFsaXplKGNoaWxkcmVuKTsKICAgICAgICB9CiAgICAgICAgaW50IHdpZHRoID0gd0hpbnQsIGhlaWdodCA9IGhIaW50OwogICAgICAgIGlmICh3SGludCA9PSBTV1QuREVGQVVMVCkKICAgICAgICAgICAgd2lkdGggPSBtYXhXaWR0aDsKICAgICAgICBpZiAoaEhpbnQgPT0gU1dULkRFRkFVTFQpCiAgICAgICAgICAgIGhlaWdodCA9IHRvdGFsSGVpZ2h0OwogICAgICAgIHJldHVybiBuZXcgUG9pbnQod2lkdGggKyAyICogTUFSR0lOLCBoZWlnaHQgKyAyICogTUFSR0lOKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCBsYXlvdXQoQ29tcG9zaXRlIGNvbXBvc2l0ZSwgYm9vbGVhbiBmbHVzaENhY2hlKSB7CiAgICAgICAgQ29udHJvbCBjaGlsZHJlbltdID0gY29tcG9zaXRlLmdldENoaWxkcmVuKCk7CiAgICAgICAgaWYgKGZsdXNoQ2FjaGUgfHwgc2l6ZXMgPT0gbnVsbCB8fCBzaXplcy5sZW5ndGggIT0gY2hpbGRyZW4ubGVuZ3RoKSB7CiAgICAgICAgICAgIGluaXRpYWxpemUoY2hpbGRyZW4pOwogICAgICAgIH0KICAgICAgICBSZWN0YW5nbGUgcmVjdCA9IGNvbXBvc2l0ZS5nZXRDbGllbnRBcmVhKCk7CiAgICAgICAgaW50IHggPSBNQVJHSU4sIHkgPSBNQVJHSU47CiAgICAgICAgaW50IHdpZHRoID0gTWF0aC5tYXgocmVjdC53aWR0aCAtIDIgKiBNQVJHSU4sIG1heFdpZHRoKTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIGludCBoZWlnaHQgPSBzaXplc1tpXS55OwogICAgICAgICAgICBjaGlsZHJlbltpXS5zZXRCb3VuZHMoeCwgeSwgd2lkdGgsIGhlaWdodCk7CiAgICAgICAgICAgIHkgKz0gaGVpZ2h0ICsgU1BBQ0lORzsKICAgICAgICB9CiAgICB9CgogICAgdm9pZCBpbml0aWFsaXplKENvbnRyb2wgY2hpbGRyZW5bXSkgewogICAgICAgIG1heFdpZHRoID0gMDsKICAgICAgICB0b3RhbEhlaWdodCA9IDA7CiAgICAgICAgc2l6ZXMgPSBuZXcgUG9pbnRbY2hpbGRyZW4ubGVuZ3RoXTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHNpemVzW2ldID0gY2hpbGRyZW5baV0uY29tcHV0ZVNpemUoU1dULkRFRkFVTFQsIFNXVC5ERUZBVUxULCB0cnVlKTsKICAgICAgICAgICAgbWF4V2lkdGggPSBNYXRoLm1heChtYXhXaWR0aCwgc2l6ZXNbaV0ueCk7CiAgICAgICAgICAgIHRvdGFsSGVpZ2h0ICs9IHNpemVzW2ldLnk7CiAgICAgICAgfQogICAgICAgIHRvdGFsSGVpZ2h0ICs9IChjaGlsZHJlbi5sZW5ndGggLSAxKSAqIFNQQUNJTkc7CiAgICB9Cn08L3ByZT4KCjxwPkhlcmUgaXMgc29tZSBzaW1wbGUgdGVzdCBjb2RlIHRvIHRlc3QgdGhlIDxjb2RlPkNvbHVtbkxheW91dDwvY29kZT4uClRoZSA8Yj5ncm93PC9iPiBhbmQgPGI+c2hyaW5rPC9iPiA8Y29kZT5CdXR0b25zPC9jb2RlPiBzaG93IGEgY2FsbCB0bwp0aGUgPGNvZGU+U2hlbGw8L2NvZGU+J3MgPGNvZGU+bGF5b3V0KCk8L2NvZGU+IG1ldGhvZCB0byBmb3JjZSBhCnJlLWxheW91dCBhZnRlciBjaGFuZ2luZyB0aGUgd2lkdGggb2Ygb25lIG9mIHRoZSBjaGlsZHJlbi4gQ2FsbGluZyA8Y29kZT5sYXlvdXQoKTwvY29kZT4KaXMgdGhlIHNhbWUgYXMgY2FsbGluZyA8Y29kZT5sYXlvdXQodHJ1ZTwvY29kZT4pIHdoaWNoIHRlbGxzIHRoZSA8Y29kZT5Db2x1bW5MYXlvdXQ8L2NvZGU+CnRvIGZsdXNoIGl0cyBjYWNoZXMgYmVmb3JlIHNldHRpbmcgdGhlIGJvdW5kcyBvZiB0aGUgY2hpbGRyZW4uIFRoZSA8Y29kZT5TaGVsbDwvY29kZT4KaXMgYWxzbyB0b2xkIHRvIDxjb2RlPnBhY2soKTwvY29kZT4gYWZ0ZXIgbGF5aW5nIG91dCB0aGUgY2hpbGRyZW4uIFRoaXMKZm9yY2VzIHRoZSA8Y29kZT5TaGVsbDwvY29kZT4gdG8gdGFrZSB0aGUgbmV3IHNpemUuPC9wPgoKPHByZT5pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0Lio7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy4qOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC4qOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy4qOwoKcHVibGljIGNsYXNzIENvbHVtbkxheW91dFRlc3QgewogICAgc3RhdGljIFNoZWxsIHNoZWxsOwogICAgc3RhdGljIEJ1dHRvbiBidXR0b24zOwoKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKICAgICAgICBEaXNwbGF5IGRpc3BsYXkgPSBuZXcgRGlzcGxheSgpOwogICAgICAgIHNoZWxsID0gbmV3IFNoZWxsKGRpc3BsYXkpOwogICAgICAgIHNoZWxsLnNldExheW91dChuZXcgQ29sdW1uTGF5b3V0KCkpOwogICAgICAgIG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKS5zZXRUZXh0KCJCMSIpOwogICAgICAgIG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKS5zZXRUZXh0KCJWZXJ5IFdpZGUgQnV0dG9uIDIiKTsKICAgICAgICAoYnV0dG9uMyA9IG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKSkuc2V0VGV4dCgiQnV0dG9uIDMiKTsKICAgICAgICBCdXR0b24gZ3JvdyA9IG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKTsKICAgICAgICBncm93LnNldFRleHQoIkdyb3cgQnV0dG9uIDMiKTsKICAgICAgICBncm93LmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewogICAgICAgICAgICBwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CiAgICAgICAgICAgICAgICBidXR0b24zLnNldFRleHQoIkV4dHJlZW1lbHkgV2lkZSBCdXR0b24gMyIpOwogICAgICAgICAgICAgICAgc2hlbGwubGF5b3V0KCk7CiAgICAgICAgICAgICAgICBzaGVsbC5wYWNrKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgICBCdXR0b24gc2hyaW5rID0gbmV3IEJ1dHRvbihzaGVsbCwgU1dULlBVU0gpOwogICAgICAgIHNocmluay5zZXRUZXh0KCJTaHJpbmsgQnV0dG9uIDMiKTsKICAgICAgICBzaHJpbmsuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKICAgICAgICAgICAgICAgIGJ1dHRvbjMuc2V0VGV4dCgiQnV0dG9uIDMiKTsKICAgICAgICAgICAgICAgIHNoZWxsLmxheW91dCgpOwogICAgICAgICAgICAgICAgc2hlbGwucGFjaygpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgICAgc2hlbGwucGFjaygpOwogICAgICAgIHNoZWxsLm9wZW4oKTsKICAgICAgICB3aGlsZSAoIXNoZWxsLmlzRGlzcG9zZWQoKSkgewogICAgICAgICAgICBpZiAoIWRpc3BsYXkucmVhZEFuZERpc3BhdGNoKCkpCiAgICAgICAgICAgICAgICBkaXNwbGF5LnNsZWVwKCk7CiAgICAgICAgfQogICAgfQp9PC9wcmU+Cgo8cD5JZiB3ZSBydW4gdGhlIHRlc3QgY29kZSwgdGhlIHdpbmRvdyBvbiB0aGUgbGVmdCBhcHBlYXJzLiBQcmVzc2luZwp0aGUgR3JvdyBCdXR0b24gMyBidXR0b24gcmVzdWx0cyBpbiB0aGUgd2luZG93IG9uIHRoZSByaWdodC4gUmVzaXppbmcKdGhlIHdpbmRvdyB3aXRoIHRoZSBtb3VzZSB3aWxsIGFsc28gbWFrZSB0aGUgYnV0dG9ucyB3aWRlciAob3IgbmFycm93ZXIpCmJ1dCB0aGV5IGRvIG5vdCBncm93IHRhbGxlci48L3A+Cgo8aW1nIHNyYz0iaW1hZ2VzL0N1c3RvbUxheW91dC5qcGciIC8+IDxpbWcKCXNyYz0iaW1hZ2VzL0N1c3RvbUxheW91dFJlc2l6ZWQuanBnIiAvPgoKPGgzPk92ZXJyaWRpbmcgQ29tcG9zaXRlPC9oMz4KCjxwPklmIHlvdSBhcmUgd3JpdGluZyB5b3VyIG93biB3aWRnZXQsIGFzIG91dGxpbmVkIGluIDxhCglocmVmPSJodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2FydGljbGVzL0FydGljbGUtV3JpdGluZyUyMFlvdXIlMjBPd24lMjBXaWRnZXQvV3JpdGluZyUyMFlvdXIlMjBPd24lMjBXaWRnZXQuaHRtIj5DcmVhdGluZwpZb3VyIE93biBXaWRnZXRzIFVzaW5nIFNXVDwvYT4sIGFuZCB5b3Ugc3ViY2xhc3MgQ29tcG9zaXRlLCB0aGVuIGhlcmUgYXJlIGEKZmV3IHBvaW50cyB0byBjb25zaWRlciBmb3IgeW91ciBpbXBsZW1lbnRhdGlvbjo8L2E+PC9wPgoKPHVsPgoJPGxpPklmIHlvdSBhcmUgcHJvdmlkaW5nIHRyaW1taW5ncyBpbiB5b3VyIG5ldyA8Y29kZT5Db21wb3NpdGU8L2NvZGU+LAoJbWFrZSBzdXJlIHRvIG92ZXJyaWRlIGJvdGggPGNvZGU+Y29tcHV0ZVRyaW0oKTwvY29kZT4gYW5kIDxjb2RlPmdldENsaWVudEFyZWEoKTwvY29kZT4uPC9saT4KCTxsaT5OZXZlciBvdmVycmlkZSA8Y29kZT5sYXlvdXQoKTwvY29kZT4sIGJ1dCB5b3UgbWF5IG92ZXJyaWRlIDxjb2RlPmxheW91dChib29sZWFuKTwvY29kZT4uPC9saT4KPC91bD4KCjxwPlNvbWV0aW1lcyB5b3Ugd2FudCB5b3VyIG5ldyA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IHRvIGhhdmUgYQpzcGVjaWZpYyBsb29rLCBhbmQgeW91IGRvbid0IHdhbnQgdGhlIGFwcGxpY2F0aW9uIHRvIGJlIGFibGUgdG8gc3BlY2lmeQphIGxheW91dC4gWW91ciBuZXcgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiB3b3VsZCBlaXRoZXIgZG8gaXRzIGxheW91dCBpbgphIHJlc2l6ZSBoYW5kbGVyIG9yIHVzaW5nIGEgcHJpdmF0ZSBjdXN0b20gbGF5b3V0LiBJbiBlaXRoZXIgY2FzZSwgeW91CndpbGwgcHJvYmFibHkgd2FudCB0byBkbyB0aGUgZm9sbG93aW5nOjwvcD4KCjx1bD4KCTxsaT5PdmVycmlkZSA8Y29kZT5zZXRMYXlvdXQoKTwvY29kZT4gdG8gZG8gbm90aGluZy48L2xpPgoJPGxpPk92ZXJyaWRlIDxjb2RlPmxheW91dChib29sZWFuKTwvY29kZT4gdG8gY2FsbCB5b3VyIGxheW91dAoJY29kZS48L2xpPgoJPGxpPk92ZXJyaWRlIDxjb2RlPmNvbXB1dGVTaXplKCk8L2NvZGU+IHRvIGNvcnJlY3RseSBjb21wdXRlIHRoZQoJc2l6ZSBvZiB5b3VyIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4uPC9saT4KPC91bD4KCgo8aDI+U3VtbWFyeTwvaDI+Cgo8cD5TV1QgcHJvdmlkZXMgc2V2ZXJhbCBkaWZmZXJlbnQgd2F5cyB0byBsYXkgb3V0IHdpZGdldHMuIFRoZQpzaW1wbGVzdCBtZXRob2QsIGFuZCB0aGUgb25lIHlvdSB3aWxsIHR5cGljYWxseSB1c2UsIGlzIHRvIHVzZSBvbmUgb2YKdGhlIHN0YW5kYXJkIDxjb2RlPkxheW91dDwvY29kZT4gY2xhc3NlczogPGNvZGU+RmlsbExheW91dDwvY29kZT4sIDxjb2RlPlJvd0xheW91dDwvY29kZT4sCjxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+IG9yIDxjb2RlPkZvcm1MYXlvdXQ8L2NvZGU+LjwvcD4KCgo8cD5JbiBjZXJ0YWluIGNhc2VzIHlvdSBtYXkgd2FudCB0byB3cml0ZSB5b3VyIG93biA8Y29kZT5MYXlvdXQ8L2NvZGU+CmNsYXNzIHRvIHByb3ZpZGUgYSB2ZXJ5IHNwZWNpZmljIGxvb2sgb3IgdG8gcmV1c2UgdmVyeSBzaW1pbGFyIGxheW91dApjb2RlLCBidXQgb2Z0ZW4gYSByZXNpemUgbGlzdGVuZXIgb24gdGhlIHBhcmVudCB3aWRnZXQgd2lsbCBzdWZmaWNlLjwvcD4KCgoKPHA+Rm9yIGZ1cnRoZXIgYXNzaXN0YW5jZSBpbiB1bmRlcnN0YW5kaW5nIHRoZSBzdGFuZGFyZCBTV1QgPGNvZGU+TGF5b3V0PC9jb2RlPgpjbGFzc2VzLCBzZWUgdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvc3d0L3NuaXBwZXRzIj5TV1QgU25pcHBldHM8L2E+LjwvcD4KPC9kaXY+Cgo8L2JvZHk+CgoKCgo8L2h0bWw+