[omniORB] struct extraction problem...
Debashish Ghosh
debashish772000@yahoo.com
Tue, 4 Dec 2001 11:48:24 -0800 (PST)
--0-126301472-1007495304=:37530
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
hi folks,
I have a problem while extracting a struct which
indicates Date. The struct is simple consisting of
year, month, date, hour , minute ,second all ints. Now
this is contained in another struct which contains the
name of the parameter,its datatype and the data which
in case of date is the above date struct. Now I am
sending a sequence of such struct that contains name-
value- datatype. I have 2 date parameters - StartDate
and EndDate whose value is of type struct Date. My
client is Java IDL and before the CORBA call the
values of both these dates are diferent. But at the
C++ side implemented by OMNI ORB the EndDate Value and
the StartDate value become same though their parameter
names in the sequence is different. Somehow the
EndDate value gets overwritten on the StartDateValue.
I'm really stuck up . It wud be grateful if u cud give
me some solution.. I'm also attaching the java file on
the client side . The C++ file on the server side and
the idl file.
Thanx
Debashish
__________________________________________________
Do You Yahoo!?
Buy the perfect holiday gifts at Yahoo! Shopping.
http://shopping.yahoo.com
--0-126301472-1007495304=:37530
Content-Type: text/plain; name="CtRepCrystal.cpp"
Content-Description: CtRepCrystal.cpp
Content-Disposition: inline; filename="CtRepCrystal.cpp"
/*********************************************************************
* purpose : TD 519 Changed the extension size
* name : Amardeep
* date : 10-Oct-2001
/*********************************************************************
* purpose : Crystal Reporting Server
* name : Amardeep
* date : 1-Apr-2001
* module : Report Manager
// todo:
// The PEStartPrintJob() is being called from each exportFormat()..
**********************************************************************/
#include <windows.h>
#include <iostream.h>
#include <stdlib.h>
#include <string.h>
#include <CtRepCrystal.h>
#include <CtRepServer.h>
/************************************************************************************/
// the implementation of CtRepCrystal.. //
/**
no-arg ctor initializes the report print engine.
*/
CtRepCrystal::CtRepCrystal() {
ctlog << "CtRepCrystal()" << endl;
// -- opening engine
if (!PEOpenEngine()) {
ctlog << "PEOpenEngine prob" << endl;
// todo: log error
} // if
ctlog << "PEOpenEngine thru.." << endl;
this->mgErrorText = NULL;
this->mgGeneratedFileLocation = NULL;
this->mgTemplateFile = NULL;
} // CtRepCrystal()
/**
dtor
closes the report print engine
*/
CtRepCrystal::~CtRepCrystal() {
ctlog << "~CtRepCrystal()" << endl;
while(!PECanCloseEngine()) {
; // into a loop while cannot close engine..
} // while
PECloseEngine();
ctlog << "Closed the engine.." << endl;
// free used up memory resources..
free(this->mgErrorText);
free(this->mgGeneratedFileLocation);
free(this->mgTemplateFile);
ctlog << "~CtRepCrystal()" << endl;
} // ~CtRepCrystal()
/**
* The entry point of the CtRepCrystal object for generation of report.
*/
bool CtRepCrystal::generateReport(
const char * igDataSourceName
, const char * igDbServerName
, const char * igDbUserName
, const char * igDbUserPassword
, const char * igFileAccessPrefix
, const char * igGeneratedFileLocation
, const CRYSTALVECTORPARAM iCRYSTALVECTORPARAMParaInfo
, const char * igTemplateFileInfo
, const CRYSTALVECTORINT iCRYSTALVECTORINTOutputFormatInfo
, CRYSTALVECTORError iCRYSTALVECTORErrorInfo
) {
ctlog << "CtRepCrystal::generateReport(...)" << endl;
// if any of the input paras are null, return with appropriatte mesg..
if(igDataSourceName == '\0') {
char lgErrorString[] = "Data source name passed is null..";
strcat(this->mgErrorText, MESSAGE_SEPARATOR);
strcat(this->mgErrorText, lgErrorString);
iCRYSTALVECTORErrorInfo.insert(iCRYSTALVECTORErrorInfo.end(), this->mgErrorText);
return false;
} // if
if(igDbServerName == '\0') {
char lgErrorString[] = "Database server name passed is null..";
strcat(this->mgErrorText, MESSAGE_SEPARATOR);
strcat(this->mgErrorText, lgErrorString);
iCRYSTALVECTORErrorInfo.insert(iCRYSTALVECTORErrorInfo.end(), this->mgErrorText);
return false;
} // if
if(igDbUserName == '\0') {
char lgErrorString[] = "Database user name passed is null..";
strcat(this->mgErrorText, MESSAGE_SEPARATOR);
strcat(this->mgErrorText, lgErrorString);
iCRYSTALVECTORErrorInfo.insert(iCRYSTALVECTORErrorInfo.end(), this->mgErrorText);
return false;
} // if
if(igDbUserPassword == '\0') {
char lgErrorString[] = "Database user password passed is null..";
strcat(this->mgErrorText, MESSAGE_SEPARATOR);
strcat(this->mgErrorText, lgErrorString);
iCRYSTALVECTORErrorInfo.insert(iCRYSTALVECTORErrorInfo.end(), this->mgErrorText);
return false;
} // if
// not checking for file access prefix..may or may not exist..
if(igGeneratedFileLocation == '\0') {
char lgErrorString[] = "Generated file locaiton passed is null..";
strcat(this->mgErrorText, MESSAGE_SEPARATOR);
strcat(this->mgErrorText, lgErrorString);
iCRYSTALVECTORErrorInfo.insert(iCRYSTALVECTORErrorInfo.end(), this->mgErrorText);
return false;
} // if
if(igTemplateFileInfo == '\0') {
char lgErrorString[] = "Template file info passed is null..";
strcat(this->mgErrorText, MESSAGE_SEPARATOR);
strcat(this->mgErrorText, lgErrorString);
iCRYSTALVECTORErrorInfo.insert(iCRYSTALVECTORErrorInfo.end(), this->mgErrorText);
return false;
} // if
// checking thru
// -- set the members
if(!setGeneratedFileLocation(igFileAccessPrefix, igGeneratedFileLocation)) {
ctlog << "setGeneratedFileLocation() failed" << endl;
// populating error member..
// todo: how would this happen in case of mem failure..?
char lgErrorString[] = "setGeneratedFileLocation() failed";
strcat(this->mgErrorText, MESSAGE_SEPARATOR);
strcat(this->mgErrorText, lgErrorString);
iCRYSTALVECTORErrorInfo.insert(iCRYSTALVECTORErrorInfo.end(), this->mgErrorText);
return false;
} // if
if(!setTemplateFile(igFileAccessPrefix, igTemplateFileInfo)) {
ctlog << "setTemplateFile() failed" << endl;
// populating error member..
// todo: how would this happen in case of mem failure..?
char lgErrorString[] = "setTemplateFile() failed";
strcat(this->mgErrorText, MESSAGE_SEPARATOR);
strcat(this->mgErrorText, lgErrorString);
iCRYSTALVECTORErrorInfo.insert(iCRYSTALVECTORErrorInfo.end(), this->mgErrorText);
return false;
} // if
// -- open the print job
if(!openPrintJob()) {
ctlog << "openPrintJob() failed" << endl;
// populating error member..
char lgErrorString[] = "openPrintJob() failed";
strcat(this->mgErrorText, MESSAGE_SEPARATOR);
strcat(this->mgErrorText, lgErrorString);
iCRYSTALVECTORErrorInfo.insert(iCRYSTALVECTORErrorInfo.end(), this->mgErrorText);
return false;
} // if
// -- connect db
if(!getDBConnection(igDataSourceName, igDbServerName, igDbUserName, igDbUserPassword)) {
ctlog << "getDBConnection() failed" << endl;
// populating error member..
char lgErrorString[] = "getDBConnection() failed";
strcat(this->mgErrorText, MESSAGE_SEPARATOR);
strcat(this->mgErrorText, lgErrorString);
iCRYSTALVECTORErrorInfo.insert(iCRYSTALVECTORErrorInfo.end(), this->mgErrorText);
return false;
} // if
// -- set the paras
if(!setReportParameters(iCRYSTALVECTORPARAMParaInfo)) {
ctlog << "setReportParameters() failed" << endl;
// populating error member..
char lgErrorString[] = "setReportParameters() failed";
strcat(this->mgErrorText, MESSAGE_SEPARATOR);
strcat(this->mgErrorText, lgErrorString);
iCRYSTALVECTORErrorInfo.insert(iCRYSTALVECTORErrorInfo.end(), this->mgErrorText);
return false;
} // if
// -- export
if(!exportReport(iCRYSTALVECTORINTOutputFormatInfo, iCRYSTALVECTORErrorInfo)) {
ctlog << "exportReport() failed" << endl;
// populating error member..
char lgErrorString[] = "exportReport() failed";
strcat(this->mgErrorText, MESSAGE_SEPARATOR);
strcat(this->mgErrorText, lgErrorString);
iCRYSTALVECTORErrorInfo.insert(iCRYSTALVECTORErrorInfo.end(), this->mgErrorText);
return false;
} // if
ctlog << "leaving CtRepCrystal::generateReport(...)" << endl;
return true;
} // generateReport()
/**
* Sets the values from the arguments to the member objects of CtRepCrystal.
*/
bool CtRepCrystal::setGeneratedFileLocation(
const char* igFileAccessPrefix
, const char *igGeneratedFileLocation
) {
ctlog << "setGeneratedFileLocation()" << endl;
int liLocationNameLen = strlen(igFileAccessPrefix) + strlen(igGeneratedFileLocation) + 1;
this->mgGeneratedFileLocation = new char[liLocationNameLen];
if(this->mgGeneratedFileLocation == 0) { // if new failed..
ctlog << "new allocation failed!! Memory crunch!!" << endl;
// populating error member..
/*
char lgErrorText[] = "new allocaiton failure!! Memory crunch!!";
this->mgErrorText = new char[strlen(lgErrorText)];
strcpy(this->mgErrorText, lgErrorText);
*/
return false;
} // if
strcpy(this->mgGeneratedFileLocation, igFileAccessPrefix);
strcat(this->mgGeneratedFileLocation, igGeneratedFileLocation);
ctlog << "generated file location: " << this->mgGeneratedFileLocation << endl;
return true;
} // setGeneratedFileLocation()
/**
* Sets the values from the arguments to the member objects of CtRepCrystal.
*/
bool CtRepCrystal::setTemplateFile(
const char* igFileAccessPrefix
, const char* igTemplateFilesInfo
) {
ctlog << "setTemplateFile()" << endl;
int liFileNameLen = strlen(igFileAccessPrefix) + strlen(igTemplateFilesInfo) + 1;
this->mgTemplateFile = new char[liFileNameLen];
if(this->mgTemplateFile == 0) { // if new failed..
ctlog << "new allocation failed!! Memory crunch!!" << endl;
return false;
} // if
strcpy(this->mgTemplateFile, igFileAccessPrefix);
strcat(this->mgTemplateFile, igTemplateFilesInfo);
ctlog << "template file name set : " << this->mgTemplateFile << endl;
return true;
} // setTemplateFile()
/**
* Opens the Print Job with Crystal.
* Note: The templateFileName expected is in absolute naming convention
* also sets the templateFile member.
*/
bool CtRepCrystal::openPrintJob(void) {
ctlog << "openPrintJob()" << endl;
ctlog << "calling openPrintJob for file: " << this->mgTemplateFile << endl;
this->msJobHandle = PEOpenPrintJob(this->mgTemplateFile);
if (this->msJobHandle == 0) {
ctlog << "PEOpenPrintJob failed.." << endl;
ReportError(this->msJobHandle);
return false;
} // if
ctlog << "PEOpenPrintJob thru" << endl;
return true;
} // openPrintJob()
/**
* Crystal connects to the DataBase on the basis of the argument information.
*/
bool CtRepCrystal::getDBConnection(
const char* igDataSourceName
, const char* igDbServerName
, const char* igDbUserName
, const char* igDbUserPassword
) {
ctlog << "getDBConnection()" << endl;
// the database connection parameters
char lgServerName[PE_SERVERNAME_LEN];
char lgDatabaseName[PE_DATABASENAME_LEN];
char lgUserId[PE_USERID_LEN];
char lgPassword[PE_PASSWORD_LEN];
strcpy(lgServerName, igDataSourceName);
strcpy(lgDatabaseName, igDbServerName);
strcpy(lgUserId, igDbUserName);
strcpy(lgPassword, igDbUserPassword);
ctlog << "getting db connection for.." << endl;
ctlog << lgServerName << endl;
ctlog << lgDatabaseName << endl;
ctlog << lgUserId << endl;
ctlog << lgPassword << endl;
// popluating the log info structure..
PELogOnInfo objPELogOnInfo;
PELogOnInfo *ptrPELogOnInfo = &objPELogOnInfo;
objPELogOnInfo.StructSize = sizeof(PELogOnInfo);
strcpy(objPELogOnInfo.ServerName, lgServerName);
strcpy(objPELogOnInfo.DatabaseName, lgDatabaseName);
strcpy(objPELogOnInfo.UserID, lgUserId);
strcpy(objPELogOnInfo.Password, lgPassword);
if(!PESetNthTableLogOnInfo(this->msJobHandle, 0, ptrPELogOnInfo, true)) {
ctlog << "PESetNthTableLogOnInfo prob" << endl;
ReportError(this->msJobHandle);
return false; //exit(1);
} // if
ctlog << "thru PESetNthTableLogOnInfo" << endl;
return true;
} // getDBConnection()
/**
* Sets the parameters for the report execution parsing through the argument object.
*/
bool CtRepCrystal::setReportParameters(
const CRYSTALVECTORPARAM iCRYSTALVECTORPARAMParaInfo
) {
ctlog << "setReportParameters()" << endl;
// determining the number of parameters sent..
int liNoOfParameters = iCRYSTALVECTORPARAMParaInfo.size();
ctlog << "Number of parameters sent to call: " << liNoOfParameters << endl;
// determining the number of parameters required in the report's template file..
int liTotalRepParameters = PEGetNParameterFields(this->msJobHandle);
ctlog << "num of report paras of the template: " << liTotalRepParameters << endl;
// loop for all the report template parameters..
for(int j=0 ; j<liTotalRepParameters ; j++) {
PEParameterFieldInfo objPEParameterFieldInfo;
PEParameterFieldInfo *ptrPEParameterFieldInfo = &objPEParameterFieldInfo;
// Change made by Rajesh
// The object needs to be intialized before being used for the method call.
ptrPEParameterFieldInfo->StructSize = PE_SIZEOF_PARAMETER_FIELD_INFO;
ptrPEParameterFieldInfo->DefaultValueSet = FALSE;
ptrPEParameterFieldInfo->CurrentValueSet = FALSE;
// End change
// Fetching the Parameter Field info for the current Parameter..
if(!PEGetNthParameterField(this->msJobHandle, j, ptrPEParameterFieldInfo)) {
ctlog << ptrPEParameterFieldInfo->StructSize << endl;
ctlog << ptrPEParameterFieldInfo->Name << endl;
ctlog << ptrPEParameterFieldInfo->ReportName << endl;
ctlog << ptrPEParameterFieldInfo->ValueType << endl;
ctlog << "PEGetNthParameterField() failed" << endl;
ReportError(this->msJobHandle);
return false;
} // if
ctlog << "Current value of j: " << j << endl;
ctlog << "ptrPEParameterFieldInfo->Name : " << ptrPEParameterFieldInfo->Name << endl;
ctlog << "ptrPEParameterFieldInfo->ValueType: " << ptrPEParameterFieldInfo->ValueType << endl;
ctlog << "ptrPEParameterFieldInfo->ReportName: " << ptrPEParameterFieldInfo->ReportName << endl;
// looking for the corresponding Parameter from the
// method argument having the same name as the current..
for(int k=0 ; k < liNoOfParameters ; k++) {
// current object of the argument vector..
CrystalParameterInfoStruct lCRYSTALVECTORPARAMParaObj = iCRYSTALVECTORPARAMParaInfo[k];
// todo: Amardeep: may not need all of this logging..
ctlog << "Current value of k: " << k << endl;
ctlog << "mgParameterName: " << lCRYSTALVECTORPARAMParaObj.mgParameterName << endl;
ctlog << "objPEParameterFieldInfo.Name: " << objPEParameterFieldInfo.Name << endl;
ctlog << "ptrPEParameterFieldInfo->Name: " << ptrPEParameterFieldInfo->Name << endl;
// if followg returns 0, the 2 strings match..
if(!strcmpi(objPEParameterFieldInfo.Name, lCRYSTALVECTORPARAMParaObj.mgParameterName)) {
ctlog << "found matching Parameter object.." << endl;
// found a matching Parameter object..
char ReportName[PE_PF_REPORT_NAME_LEN];
strcpy(ReportName, objPEParameterFieldInfo.ReportName);
objPEParameterFieldInfo.DefaultValueSet = FALSE;
objPEParameterFieldInfo.CurrentValueSet = FALSE;
// initializing the Value object for the parameter..
PEValueInfo objPEValueInfo;
PEValueInfo *ptrPEValueInfo = &objPEValueInfo;
// Start: Amardeep: 4-Dec-01
if (!PEConvertPFInfoToVInfo(ptrPEParameterFieldInfo
, ptrPEParameterFieldInfo->ValueType
, ptrPEValueInfo)) {
ctlog << "PEConvertPFInfoToVInfo() failed" << endl;
ReportError(this->msJobHandle);
return false;
} // if
//objPEValueInfo.StructSize = sizeof(PEValueInfo);
//objPEValueInfo.valueType = objPEParameterFieldInfo.ValueType;
// End: Amardeep: 4-Dec-01
// todo: verification of datatype across report template and func argument
ctlog << "going into the switch.." << endl;
// Start: Amardeep: 4-Dec-01
// The check for the ValueType happens on the retrieved object
// while the setting happens on the Value object..
//switch(objPEValueInfo.valueType) {
switch(objPEParameterFieldInfo.ValueType) {
// End: Amardeep: 4-Dec-01
case PE_PF_BOOLEAN:
ctlog << "BOOLEAN" << endl;
if(!strcmpi(lCRYSTALVECTORPARAMParaObj.mgParameterDatatype, "boolean")) {
if(!strcmpi(lCRYSTALVECTORPARAMParaObj.mCrystalParameterValueUnion.stringVal, "TRUE")) {
objPEValueInfo.viBoolean = 1;
} else {
objPEValueInfo.viBoolean = 0;
} // if..else
} // if
break; // PE_PF_BOOLEAN
case PE_PF_DATE:
ctlog << "DATE" << endl;
if(!strcmpi(lCRYSTALVECTORPARAMParaObj.mgParameterDatatype, "date")) {
CrystalDateStruct *lCrystalDateStruct;
lCrystalDateStruct = lCRYSTALVECTORPARAMParaObj.mCrystalParameterValueUnion.CrystalDateVal;
int liyear = lCrystalDateStruct->year;
ctlog << "Year: " << liyear << endl;
if (liyear) {
objPEValueInfo.viDate[0] = liyear;
} // if
int limonth = lCrystalDateStruct->month;
ctlog << "Month: " << limonth << endl;
if (limonth) {
objPEValueInfo.viDate[1] = limonth;
} // if
int liday = lCrystalDateStruct->day;
ctlog << "Day: " << liday << endl;
if (liday) {
objPEValueInfo.viDate[2] = liday;
} // if
} // if : date
break; // PE_PF_DATE
case PE_PF_NUMBER:
case PE_PF_CURRENCY:
ctlog << "NUMBER/CURRENCY" << endl;
// Note: needs stdlib.h
if(!strcmpi(lCRYSTALVECTORPARAMParaObj.mgParameterDatatype, "double")) {
objPEValueInfo.viNumber = lCRYSTALVECTORPARAMParaObj.mCrystalParameterValueUnion.doubleVal;
} else {
ctlog << "setting the long value.." << endl;
objPEValueInfo.viNumber = lCRYSTALVECTORPARAMParaObj.mCrystalParameterValueUnion.longVal;
} // if..else
break; // PE_PF_NUMBER/PE_PF_CURRENCY
case PE_PF_STRING:
ctlog << "STRING" << endl;
if(!strcmpi(lCRYSTALVECTORPARAMParaObj.mgParameterDatatype, "string")) {
strcpy(objPEValueInfo.viString, lCRYSTALVECTORPARAMParaObj.mCrystalParameterValueUnion.stringVal);
} // if
break; // PE_PF_STRING
case PE_PF_TIME:
ctlog << "TIME" << endl;
if(!strcmpi(lCRYSTALVECTORPARAMParaObj.mgParameterDatatype, "time")) {
CrystalDateStruct *lCrystalDateStruct;
lCrystalDateStruct = lCRYSTALVECTORPARAMParaObj.mCrystalParameterValueUnion.CrystalDateVal;
int lihour = lCrystalDateStruct->hour;
ctlog << "Hour: " << lihour << endl;
if (lihour) {
objPEValueInfo.viTime[0] = lihour;
} // if
int liminute = lCrystalDateStruct->minute;
ctlog << "Minute: " << liminute << endl;
if (liminute) {
objPEValueInfo.viTime[1] = liminute;
} // if
int lisecond = lCrystalDateStruct->second;
ctlog << "Second: " << lisecond << endl;
if (lisecond) {
objPEValueInfo.viTime[2] = lisecond;
} // if
} // if: time
break; // PE_PF_TIME
case PE_PF_DATETIME:
ctlog << "DATETIME" << endl;
if(!strcmpi(lCRYSTALVECTORPARAMParaObj.mgParameterDatatype, "datetime")) {
CrystalDateStruct *lCrystalDateStruct;
lCrystalDateStruct = lCRYSTALVECTORPARAMParaObj.mCrystalParameterValueUnion.CrystalDateVal;
int liyear = lCrystalDateStruct->year;
ctlog << "Year: " << liyear << endl;
if (liyear) {
objPEValueInfo.viDateTime[0] = liyear;
} // if
int limonth = lCrystalDateStruct->month;
ctlog << "Month: " << limonth << endl;
if (limonth) {
objPEValueInfo.viDateTime[1] = limonth;
} // if
int liday = lCrystalDateStruct->day;
ctlog << "Day: " << liday << endl;
if (liday) {
objPEValueInfo.viDateTime[2] = liday;
} // if
int lihour = lCrystalDateStruct->hour;
ctlog << "Hour: " << lihour << endl;
if (lihour) {
objPEValueInfo.viDateTime[3] = lihour;
} // if
int liminute = lCrystalDateStruct->minute;
ctlog << "Minute: " << liminute << endl;
if (liminute) {
objPEValueInfo.viDateTime[4] = liminute;
} // if
int lisecond = lCrystalDateStruct->second;
ctlog << "Second: " << lisecond << endl;
if (lisecond) {
objPEValueInfo.viDateTime[5] = lisecond;
} // if
} // if : "datetime"
break; // PE_PF_DATETIME
default:
ctlog << "in default" << endl;
break;
} // switch: objPEValueInfo.valueType
// Start: Amardeep: 4-Dec-01
//if(!PEAddParameterCurrentValue(this->msJobHandle,
// objPEParameterFieldInfo.Name,
// ReportName,
// ptrPEValueInfo)) {
// ctlog << "PEAddParameterCurrentValue() failed" << endl;
// ReportError(this->msJobHandle);
// // todo: err logging
// return false;
//} // if
if (!PEConvertVInfoToPFInfo(ptrPEValueInfo
, ptrPEParameterFieldInfo->ValueType
, ptrPEParameterFieldInfo->CurrentValue)) {
ctlog << "PEConvertVInfoToPFInfo() failed" << endl;
ReportError(this->msJobHandle);
return false;
} // if
// Set current value flag
objPEParameterFieldInfo.CurrentValueSet = 1;
// Set the parameter field value
if (!PESetNthParameterField(this->msJobHandle, j, ptrPEParameterFieldInfo)) {
ctlog << "PEConvertVInfoToPFInfo() failed" << endl;
ReportError(this->msJobHandle);
return false;
} // if
// End: Amardeep: 4-Dec-01
break;
} // if: (!strcmpi(objPEParameterFieldInfo.Name, lCRYSTALVECTORPARAMParaObj.mgParameterName)
} // for : k<liNoOfParameters
} // for : j<liTotalRepParameters
ctlog << "parameter value set" << endl;
return true;
} // setReportParameters()
/**
* Calls the respective exportxxx() method for each of the output formats.
*/
bool CtRepCrystal::exportReport(
const CRYSTALVECTORINT iCRYSTALVECTORINTOutputFormatInfo
, CRYSTALVECTORError iCRYSTALVECTORErrorInfo
) {
ctlog << "exportReport()" << endl;
// generically set the ExportWindowDisplay to false
PEEnableProgressDialog(this->msJobHandle, false);
int liNoOfFormats = iCRYSTALVECTORINTOutputFormatInfo.size();
ctlog << "Number of output formats: " << liNoOfFormats << endl;
for(int i=0 ; i<liNoOfFormats ; i++) {
long liFormat = iCRYSTALVECTORINTOutputFormatInfo[i];
ctlog << "current format value: " << liFormat << endl;
switch(liFormat) {
case PDF_FORMAT:
if(!exportPDF()) {
ctlog << "exportPDF() failed.." << endl;
// populating error member..
char lgErrorString[] = "exportPDF() failed";
strcat(this->mgErrorText, MESSAGE_SEPARATOR);
strcat(this->mgErrorText, lgErrorString);
iCRYSTALVECTORErrorInfo.insert(iCRYSTALVECTORErrorInfo.end(), this->mgErrorText);
return false;
} // if
break; // PDF_FORMAT
case HTML_FORMAT:
if(!exportHTML()) {
ctlog << "exportHTML() failed.." << endl;
// populating error member..
char lgErrorString[] = "exportHTML() failed";
strcat(this->mgErrorText, MESSAGE_SEPARATOR);
strcat(this->mgErrorText, lgErrorString);
iCRYSTALVECTORErrorInfo.insert(iCRYSTALVECTORErrorInfo.end(), this->mgErrorText);
return false;
} // if
break; // HTML_FORMAT
case WORD_FORMAT:
if(!exportWORD()) {
ctlog << "exportWORD() failed.." << endl;
// populating error member..
char lgErrorString[] = "exportWORD() failed";
strcat(this->mgErrorText, MESSAGE_SEPARATOR);
strcat(this->mgErrorText, lgErrorString);
iCRYSTALVECTORErrorInfo.insert(iCRYSTALVECTORErrorInfo.end(), this->mgErrorText);
return false;
} // if
break; // WORD_FORMAT
case CSV_FORMAT:
if(!exportCSV()) {
ctlog << "exportCSV() failed.." << endl;
// populating error member..
char lgErrorString[] = "exportCSV() failed";
strcat(this->mgErrorText, MESSAGE_SEPARATOR);
strcat(this->mgErrorText, lgErrorString);
iCRYSTALVECTORErrorInfo.insert(iCRYSTALVECTORErrorInfo.end(), this->mgErrorText);
return false;
} // if
break; // CSV_FORMAT
case XLS_FORMAT:
if(!exportXLS()) {
ctlog << "exportXLS() failed.." << endl;
// populating error member..
char lgErrorString[] = "exportXLS() failed";
strcat(this->mgErrorText, MESSAGE_SEPARATOR);
strcat(this->mgErrorText, lgErrorString);
iCRYSTALVECTORErrorInfo.insert(iCRYSTALVECTORErrorInfo.end(), this->mgErrorText);
return false;
} // if
break; // XLS_FORMAT
default:
ctlog << "Illegal output format!!" << endl;
// populating error member..
char lgErrorString[] = "Illegal output format!!";
strcat(this->mgErrorText, MESSAGE_SEPARATOR);
strcat(this->mgErrorText, lgErrorString);
iCRYSTALVECTORErrorInfo.insert(iCRYSTALVECTORErrorInfo.end(), this->mgErrorText);
return false;
break; // default
} // switch() : liFormat
// note:
// The following has been moved from here to the common location from where the current
// method is invoked.
/* ctlog << "starting print job.." << endl;
// -- start print job
if (!PEStartPrintJob(this->msJobHandle, true)) {
ctlog << "PEStartPrintJob failed.." << endl;
ReportError(this->msJobHandle);
return false;
} // if
*/ } // for
// end note:
ctlog << "thru exportReport().." << endl;
return true;
} // exportReport
/**
* Exporting in .pdf format carried out.
*/
bool CtRepCrystal::exportPDF() {
ctlog << "exportPDF()" << endl;
int liExtensionLen = 10;
int liFileLocationLen = strlen(this->mgGeneratedFileLocation);
int liOutputFileNameLen = liFileLocationLen + liExtensionLen;
char *outputFileName = new char[liOutputFileNameLen];
strcpy(outputFileName, this->mgGeneratedFileLocation);
strcat(outputFileName, PDF_EXT);
// -- set export options..
PEExportOptions pobjPEExportOptions;
PEExportOptions *pptrPEExportOptions = &pobjPEExportOptions;
pobjPEExportOptions.StructSize = PE_SIZEOF_EXPORT_OPTIONS;
// .. pdf options..
UXFPDFOptions pobjUXFPDFOptions;
UXFPDFOptions *pptrUXFPDFOptions = &pobjUXFPDFOptions;
pobjUXFPDFOptions.structSize = sizeof(UXFPDFOptions);
pobjUXFPDFOptions.fileName = outputFileName;
strcpy(pobjPEExportOptions.formatDLLName, PDF_DLL);
pobjPEExportOptions.formatType = UXFPDFType;
pobjPEExportOptions.formatOptions = pptrUXFPDFOptions;
// -- set destination..
UXDDiskOptions pobjUXDDiskOptions;
UXDDiskOptions *pptrUXDDiskOptions = &pobjUXDDiskOptions;
pobjUXDDiskOptions.structSize = sizeof(UXDDiskOptions);
pobjUXDDiskOptions.fileName = outputFileName;
strcpy(pobjPEExportOptions.destinationDLLName, DESTINATION_DISK_DLL);
pobjPEExportOptions.destinationType = UXDDiskType;
pobjPEExportOptions.destinationOptions = pptrUXDDiskOptions;
// -- export options..
if (!PEExportTo(this->msJobHandle, pptrPEExportOptions)) {
ctlog << "PEExportTo failed.." << endl;
ReportError(this->msJobHandle);
return false;
} // if
ctlog << "PEExportTo success.." << endl;
ctlog << "exportPDF()..starting print job.." << endl;
// -- start print job
if (!PEStartPrintJob(this->msJobHandle, true)) {
ctlog << "PEStartPrintJob failed.." << endl;
ReportError(this->msJobHandle);
return false;
} // if
delete []outputFileName;
ctlog << "exportPDF() success.." << endl;
return true;
} // exportPDF()
/**
* Exporting in .html format carried out.
*/
bool CtRepCrystal::exportHTML() {
ctlog << "exportHTML()" << endl;
int liExtensionLen = 10;
int liFileLocationLen = strlen(this->mgGeneratedFileLocation);
int liOutputFileNameLen = liFileLocationLen + liExtensionLen;
char *outputFileName = new char[liOutputFileNameLen];
strcpy(outputFileName, this->mgGeneratedFileLocation);
strcat(outputFileName, HTML_EXT);
ctlog << "output file being generated.." << outputFileName << endl;
// -- export options..
PEExportOptions objPEExportOptions;
PEExportOptions *ptrPEExportOptions = &objPEExportOptions;
objPEExportOptions.StructSize = PE_SIZEOF_EXPORT_OPTIONS;
// format options..
UXFHTML3Options objUXFHTML3Options;
UXFHTML3Options *ptrUXFHTML3Options = &objUXFHTML3Options;
objUXFHTML3Options.structSize = sizeof(UXFHTML3Options);
objUXFHTML3Options.fileName = outputFileName;
strcpy(objPEExportOptions.formatDLLName, HTML_DLL);
objPEExportOptions.formatType = UXFHTML32ExtType;
objPEExportOptions.formatOptions= ptrUXFHTML3Options;
// --
UXDDiskOptions objUXDDiskOptions;
UXDDiskOptions *ptrUXDDiskOptions = &objUXDDiskOptions;
objUXDDiskOptions.structSize = sizeof(UXDDiskOptions);
objUXDDiskOptions.fileName = outputFileName;
strcpy(objPEExportOptions.destinationDLLName, DESTINATION_DISK_DLL);
objPEExportOptions.destinationType = UXDDiskType;
objPEExportOptions.destinationOptions = ptrUXDDiskOptions;
// -- export options
if (!PEExportTo(this->msJobHandle, ptrPEExportOptions)) {
ctlog << "PEExportTo failed.." << endl;
ReportError(this->msJobHandle);
return false; //exit(1);
} // if
ctlog << "exportHTML()..starting print job.." << endl;
// -- start print job
if (!PEStartPrintJob(this->msJobHandle, true)) {
ctlog << "PEStartPrintJob failed.." << endl;
ReportError(this->msJobHandle);
return false;
} // if
delete []outputFileName; //delete outputFileName;
ctlog << "exportHTML() success.." << endl;
return true;
} // exportHTML
/**
* Exporting in .doc format carried out.
*/
bool CtRepCrystal::exportWORD() {
ctlog << "exportWORD()" << endl;
int liExtensionLen = 10;
int liFileLocationLen = strlen(this->mgGeneratedFileLocation);
int liOutputFileNameLen = liFileLocationLen + liExtensionLen;
char *outputFileName = new char[liOutputFileNameLen];
strcpy(outputFileName, this->mgGeneratedFileLocation);
strcat(outputFileName, DOC_EXT);
ctlog << "output file being generated.." << outputFileName << endl;
// -- set export options..
PEExportOptions wobjPEExportOptions;
PEExportOptions *wptrPEExportOptions = &wobjPEExportOptions;
wobjPEExportOptions.StructSize = PE_SIZEOF_EXPORT_OPTIONS;
// -- set format..no struct..
strcpy(wobjPEExportOptions.formatDLLName, DOC_DLL);
wobjPEExportOptions.formatType = UXFWordWinType;
wobjPEExportOptions.formatOptions = NULL;
// -- set destination..
UXDDiskOptions wobjUXDDiskOptions;
UXDDiskOptions *wptrUXDDiskOptions = &wobjUXDDiskOptions;
wobjUXDDiskOptions.structSize = sizeof(UXDDiskOptions);
wobjUXDDiskOptions.fileName = outputFileName;
strcpy(wobjPEExportOptions.destinationDLLName, DESTINATION_DISK_DLL);
wobjPEExportOptions.destinationType = UXDDiskType;
wobjPEExportOptions.destinationOptions = wptrUXDDiskOptions;
// -- export options
if (!PEExportTo(this->msJobHandle, wptrPEExportOptions)) {
ctlog << "PEExportTo failed.." << endl;
ReportError(this->msJobHandle);
return false; //exit(1);
} // if
ctlog << "PEExportTo success.." << endl;
ctlog << "exportWORD()..starting print job.." << endl;
// -- start print job
if (!PEStartPrintJob(this->msJobHandle, true)) {
ctlog << "PEStartPrintJob failed.." << endl;
ReportError(this->msJobHandle);
return false;
} // if
delete []outputFileName;
ctlog << "exportWORD() success.." << endl;
return true;
} // exportWORD()
/*
* Exporting in .csv format carried out.
*/
bool CtRepCrystal::exportCSV() {
// todo: the header tweaking..
ctlog << "exportCSV()" << endl;
int liExtensionLen = 10;
int liFileLocationLen = strlen(this->mgGeneratedFileLocation);
int liOutputFileNameLen = liFileLocationLen + liExtensionLen;
char *outputFileName = new char[liOutputFileNameLen];
strcpy(outputFileName, this->mgGeneratedFileLocation);
strcat(outputFileName, CSV_EXT);
// -- set export options..
PEExportOptions cobjPEExportOptions;
PEExportOptions *cptrPEExportOptions = &cobjPEExportOptions;
cobjPEExportOptions.StructSize = PE_SIZEOF_EXPORT_OPTIONS;
// -- set format..
UXFCommaTabSeparatedOptions objUXFCommaTabSeparatedOptions;
UXFCommaTabSeparatedOptions *ptrUXFCommaTabSeparatedOptions = &objUXFCommaTabSeparatedOptions;
objUXFCommaTabSeparatedOptions.structSize = sizeof(UXFCommaTabSeparatedOptions);
objUXFCommaTabSeparatedOptions.useReportNumberFormat= FALSE;
objUXFCommaTabSeparatedOptions.useReportDateFormat = FALSE; // TRUE;
strcpy(cobjPEExportOptions.formatDLLName, CSV_DLL);
cobjPEExportOptions.formatType = UXFCommaSeparatedType;
cobjPEExportOptions.formatOptions = ptrUXFCommaTabSeparatedOptions;
// -- set destination..
UXDDiskOptions cobjUXDDiskOptions;
UXDDiskOptions *cptrUXDDiskOptions = &cobjUXDDiskOptions;
cobjUXDDiskOptions.structSize = sizeof(UXDDiskOptions);
cobjUXDDiskOptions.fileName = outputFileName;
strcpy(cobjPEExportOptions.destinationDLLName, DESTINATION_DISK_DLL);
cobjPEExportOptions.destinationType = UXDDiskType;
cobjPEExportOptions.destinationOptions = cptrUXDDiskOptions;
// -- export options
if (!PEExportTo(this->msJobHandle, cptrPEExportOptions)) {
ctlog << "PEExportTo failed.." << endl;
ReportError(this->msJobHandle);
return false; //exit(1);
} // if
ctlog << "PEExportTo success.." << endl;
ctlog << "exportCSV()..starting print job.." << endl;
// -- start print job
if (!PEStartPrintJob(this->msJobHandle, true)) {
ctlog << "PEStartPrintJob failed.." << endl;
ReportError(this->msJobHandle);
return false;
} // if
delete []outputFileName;
ctlog << "exportCSV() success.." << endl;
return true;
} // exportCSV()
/**
* Exporting in .xls format carried out.
*/
bool CtRepCrystal::exportXLS() {
ctlog << "exportXLS" << endl;
int liExtensionLen = 10;
int liFileLocationLen = strlen(this->mgGeneratedFileLocation);
int liOutputFileNameLen = liFileLocationLen + liExtensionLen;
char *outputFileName = new char[liOutputFileNameLen];
strcpy(outputFileName, this->mgGeneratedFileLocation);
strcat(outputFileName, XLS_EXT);
// -- set export options..
PEExportOptions xobjPEExportOptions;
PEExportOptions *xptrPEExportOptions = &xobjPEExportOptions;
xobjPEExportOptions.StructSize = PE_SIZEOF_EXPORT_OPTIONS;
// -- set format..no struct..
// todo:type ??
strcpy(xobjPEExportOptions.formatDLLName, XLS_DLL);
xobjPEExportOptions.formatType = UXFXls5Type;
xobjPEExportOptions.formatOptions = NULL;
// -- set destination..
UXDDiskOptions xobjUXDDiskOptions;
UXDDiskOptions *xptrUXDDiskOptions = &xobjUXDDiskOptions;
xobjUXDDiskOptions.structSize = sizeof(UXDDiskOptions);
xobjUXDDiskOptions.fileName = outputFileName;
strcpy(xobjPEExportOptions.destinationDLLName, DESTINATION_DISK_DLL);
xobjPEExportOptions.destinationType = UXDDiskType;
xobjPEExportOptions.destinationOptions = xptrUXDDiskOptions;
// -- export options
if (!PEExportTo(this->msJobHandle, xptrPEExportOptions)) {
ctlog << "PEExportTo failed.." << endl;
ReportError(this->msJobHandle);
return false; //exit(1);
} // if
ctlog << "PEExportTo success.." << endl;
ctlog << "exportXLS()..starting print job.." << endl;
// -- start print job
if (!PEStartPrintJob(this->msJobHandle, true)) {
ctlog << "PEStartPrintJob failed.." << endl;
ReportError(this->msJobHandle);
return false;
} // if
delete []outputFileName;
ctlog << "exportXLS() success.." << endl;
return true;
} // exportXLS()
/**
* For the current print job, the error details are retrieved from the Crystal System.
*/
void CtRepCrystal::ReportError(
short isPrintJob
) {
ctlog << "ReportError().." << endl;
short lsErrorCode;
HANDLE lHTextHandle;
short lsTextLength;
char *lgErrorText;
lsErrorCode = PEGetErrorCode(isPrintJob);
PEGetErrorText(isPrintJob, &lHTextHandle, &lsTextLength);
lgErrorText = new char[lsTextLength]; // (char*)malloc(lsTextLength);
PEGetHandleString(lHTextHandle,
lgErrorText,
lsTextLength);
printf(lgErrorText);
printf("\n Error code is : %s", lgErrorText);
this->mgErrorText = new char[strlen(lgErrorText)];
strcpy(this->mgErrorText, lgErrorText);
free(lgErrorText);
return;
} // ReportError()
--0-126301472-1007495304=:37530
Content-Type: text/plain; name="CtRepServer.idl"
Content-Description: CtRepServer.idl
Content-Disposition: inline; filename="CtRepServer.idl"
#ifndef Reporting_idl
#define Reporting_idl
module com {
module cashtech {
module cashin {
module ctprocessing {
module ctrptmanager {
// The Date structure..
struct CtRepCorbaDate {
long year ;
long month ;
long day ;
long hour ;
long minute ;
long second ;
long nano; // ?? needed?
}; // CtRepCorbaDate
// for the values of the parameters..
enum CtRepCorbaParameterDataTypes{
eChar,
eShort,
eLong,
eFloat,
eDouble,
eString,
eDate
}; // CtRepCorbaParameterDataTypes
union CtRepCorbaParameterValue switch(CtRepCorbaParameterDataTypes){
case eChar: char charVal;
case eShort: char shortVal;
case eLong: long longVal;
case eFloat: float floatVal;
case eDouble: double doubleVal;
case eString: string stringVal;
case eDate: CtRepCorbaDate CtRepCorbaDateVal;
}; // CtRepCorbaParameterValue
// parameter details..
struct CtRepCorbaParameterInfo{
string mgParameterName;
string mgParameterDatatype;
CtRepCorbaParameterValue mCtRepCorbaParameterValueInfo;
}; // struct CtRepCorbaParameterInfo
struct CtRepCorbaTemplateFileInfo {
string templateFileName; // the actual filename with the path
string templateFileType; // the type of the file identified by its xtension
}; // struct CtRepCorbaTemplateFileInfo
typedef sequence<CtRepCorbaParameterInfo> CtRepCorbaParameterList;
typedef sequence<CtRepCorbaTemplateFileInfo> CtRepCorbaTemplateFileList;
typedef sequence<long> CtRepCorbaOutputFormatList;
typedef sequence<string> CtRepCorbaErrorList;
interface CtRepCorbaServer {
boolean generateReport(
in string igDataSourceName,
in string igDbServerName,
in string igDbUserName,
in string igDbUserPassword,
in string igRepServerName,
in string igRepServerUserName,
in string igRepServerUserPassword,
in string igFileAccessPrefix, // reference base for the template files
in string igGeneratedFileLocation, // will contain the path as to where the generated files have to be stored
in CtRepCorbaParameterList iCtRepCorbaParameterListPara,
in CtRepCorbaTemplateFileList iCtRepCorbaTemplateFileListFile,
in CtRepCorbaOutputFormatList iCtRepCorbaOutputFormatListFormat,
out CtRepCorbaErrorList oCtRepCorbaErrorListErrors
); // generateReport()
}; // interface CtRepCorbaServer
interface CtRepCorbaCrystalServer : CtRepCorbaServer {
}; // interface CtRepCorbaCrystalServer
interface CtRepCorbaActuateServer : CtRepCorbaServer {
boolean moveFileToEncyclopedia(
in string igServerName
, in string igUserName
, in string igUserPassword
, in string igFileAccessPrefix
, in CtRepCorbaTemplateFileList iCtRepCorbaTemplateFileListSource
, in CtRepCorbaTemplateFileList iCtRepCorbaTemplateFileListDestn
); // moveFileToEncyclopedia()
}; // interface CtRepCorbaActuateServer
}; // ctrptmanager
}; // ctprocessing
}; // cashin
}; // cashtech
}; // com
#endif
--0-126301472-1007495304=:37530
Content-Type: application/octet-stream; name="CrystalReport.java"
Content-Transfer-Encoding: base64
Content-Description: CrystalReport.java
Content-Disposition: attachment; filename="CrystalReport.java"
aW1wb3J0IGNvbS5jYXNodGVjaC5jYXNoaW4uY3Rwcm9jZXNzaW5nLmN0cnB0
bWFuYWdlci4qOw0KaW1wb3J0IG9yZy5hcGFjaGUubG9nNGouKjsNCmltcG9y
dCBjb20uY2FzaHRlY2guY2FzaGluLmN0dXRpbC4qOw0KaW1wb3J0IG9yZy5v
bWcuQ29zTmFtaW5nLio7DQppbXBvcnQgb3JnLm9tZy5DT1JCQS5PUkI7DQpp
bXBvcnQgamF2YS51dGlsLio7DQoNCg0KcHVibGljIGNsYXNzIENyeXN0YWxS
ZXBvcnQgew0KDQoJU3RyaW5nIG1nSG9zdE5hbWU7DQoJU3RyaW5nIG1nSG9z
dFBvcnQ7DQoJcHVibGljIENyeXN0YWxSZXBvcnQoKSB7DQoJfQ0KDQoJcHVi
bGljIHN0YXRpYyB2b2lkIG1haW4gKFN0cmluZyBhcmd2W10pIHsNCgkJU3lz
dGVtLm91dC5wcmludGxuKCJVcGRhdGVkIik7DQoNCgkJQ3J5c3RhbFJlcG9y
dCBsQ3J5c3RhbFJlcG9ydCA9IG5ldyBDcnlzdGFsUmVwb3J0KCk7DQoJCWxD
cnlzdGFsUmVwb3J0Lm1nSG9zdE5hbWUgPSAiYXN0ZXJpeCI7DQoJCWxDcnlz
dGFsUmVwb3J0Lm1nSG9zdFBvcnQgPSAiMjgwOSI7DQoNCg0KCQlTdHJpbmcg
bGdEYXRhU291cmNlTmFtZSA9ICJDQVNIUUMiOw0KCQlTdHJpbmcgbGdEYlNl
cnZlck5hbWUgPSAiYXN0ZXJpeCI7DQoJCVN0cmluZyBsZ0RiVXNlck5hbWUg
PSAiQ0FTSEFETSI7DQoJCVN0cmluZyBsZ0RiVXNlclBhc3N3b3JkID0gIkNB
U0hBRE0iOw0KCQlTdHJpbmcgbGdHZW5lcmF0ZWRGaWxlTG9jYXRpb24gPSAi
RDpcXHJlcG9ydGluZ1xcdGVzdCI7DQoNCgkJTGlua2VkTGlzdCBsQ3RSZXBF
eGVjdXRpb25QYXJhbWV0ZXJWYWx1ZUxMaXN0ID0gbmV3IExpbmtlZExpc3Qo
KTsNCg0KCQkvL0RhdGVUaW1lRm9ybWF0ID0gImRkL01NL3l5eXkgSEg6bW06
c3MiOw0KDQoJCUN0UmVwRXhlY3V0aW9uUGFyYW1ldGVySW5mbyBsQ3RSZXBF
eGVjdXRpb25QYXJhbWV0ZXJJbmZvID0gbmV3IEN0UmVwRXhlY3V0aW9uUGFy
YW1ldGVySW5mbygpOw0KDQoJCWxDdFJlcEV4ZWN1dGlvblBhcmFtZXRlcklu
Zm8ubWdQYXJhbWV0ZXJDb2RlID0gIlN0YXJ0RGF0ZSIgOw0KCQlsQ3RSZXBF
eGVjdXRpb25QYXJhbWV0ZXJJbmZvLm1pUGFyYW1ldGVyRGF0YXR5cGUgPSBD
dFV0bERhdGFUeXBlRW51bS5USU1FU1RBTVA7DQoJCWxDdFJlcEV4ZWN1dGlv
blBhcmFtZXRlckluZm8ubWdQYXJhbWV0ZXJWYWx1ZSA9ICIwMS8wMS8wMCAw
MDowMDowMCI7DQoNCg0KCQlsQ3RSZXBFeGVjdXRpb25QYXJhbWV0ZXJWYWx1
ZUxMaXN0LmFkZExhc3QobEN0UmVwRXhlY3V0aW9uUGFyYW1ldGVySW5mbyk7
DQoNCg0KDQoJCWxDdFJlcEV4ZWN1dGlvblBhcmFtZXRlckluZm8gPSBuZXcg
Q3RSZXBFeGVjdXRpb25QYXJhbWV0ZXJJbmZvKCk7DQoJCWxDdFJlcEV4ZWN1
dGlvblBhcmFtZXRlckluZm8ubWdQYXJhbWV0ZXJDb2RlID0gIkVudGl0eVR5
cGUiIDsNCgkJbEN0UmVwRXhlY3V0aW9uUGFyYW1ldGVySW5mby5taVBhcmFt
ZXRlckRhdGF0eXBlID0gQ3RVdGxEYXRhVHlwZUVudW0uSU5UOw0KCQlsQ3RS
ZXBFeGVjdXRpb25QYXJhbWV0ZXJJbmZvLm1nUGFyYW1ldGVyVmFsdWUgPSAi
Mjc0MDIiOw0KDQoJCWxDdFJlcEV4ZWN1dGlvblBhcmFtZXRlclZhbHVlTExp
c3QuYWRkTGFzdChsQ3RSZXBFeGVjdXRpb25QYXJhbWV0ZXJJbmZvKTsNCg0K
DQoNCgkJbEN0UmVwRXhlY3V0aW9uUGFyYW1ldGVySW5mbyA9IG5ldyBDdFJl
cEV4ZWN1dGlvblBhcmFtZXRlckluZm8oKTsNCgkJbEN0UmVwRXhlY3V0aW9u
UGFyYW1ldGVySW5mby5tZ1BhcmFtZXRlckNvZGUgPSAiRW5kRGF0ZSIgOw0K
CQlsQ3RSZXBFeGVjdXRpb25QYXJhbWV0ZXJJbmZvLm1pUGFyYW1ldGVyRGF0
YXR5cGUgPSBDdFV0bERhdGFUeXBlRW51bS5USU1FU1RBTVA7DQoJCWxDdFJl
cEV4ZWN1dGlvblBhcmFtZXRlckluZm8ubWdQYXJhbWV0ZXJWYWx1ZSA9ICIx
Mi8xMi8wMiAxMjoxMDoxMCI7DQoNCgkJbEN0UmVwRXhlY3V0aW9uUGFyYW1l
dGVyVmFsdWVMTGlzdC5hZGRMYXN0KGxDdFJlcEV4ZWN1dGlvblBhcmFtZXRl
ckluZm8pOw0KDQoNCg0KCQlMaW5rZWRMaXN0IGxDdFV0bE5hbWVWYWx1ZUxM
aXN0VGVtcGxhdGVGaWxlSW5mbyA9IG5ldyBMaW5rZWRMaXN0KCk7DQoNCgkJ
TGlua2VkTGlzdCBsTExpc3RPdXRwdXRGb3JtYXRzID0gbmV3IExpbmtlZExp
c3QoKTsNCg0KCQlJbnRlZ2VyIGxPdXRwdXRGb3JtYXQgPSBuZXcgSW50ZWdl
cigxMDEwNCk7DQoJCWxMTGlzdE91dHB1dEZvcm1hdHMuYWRkKGxPdXRwdXRG
b3JtYXQpOw0KDQoJCUN0VXRsTmFtZVZhbHVlIGxDdFV0bE5hbWVWYWx1ZSA9
IG5ldyBDdFV0bE5hbWVWYWx1ZSgpOw0KDQoJCVN0cmluZyBsZ0ZpbGVOYW1l
ID0gIkQ6XFxyZXBvcnRpbmdcXHRlc3QxLnJwdCI7DQoJCVN0cmluZyBsZ0Zp
bGVFeHRlbnNpb24gPSAiUlBUIjsNCgkJbEN0VXRsTmFtZVZhbHVlLm1PYmpl
Y3ROYW1lID0gbGdGaWxlTmFtZTsNCgkJbEN0VXRsTmFtZVZhbHVlLm1PYmpl
Y3RWYWx1ZSA9IGxnRmlsZUV4dGVuc2lvbjsNCg0KCQlsQ3RVdGxOYW1lVmFs
dWVMTGlzdFRlbXBsYXRlRmlsZUluZm8uYWRkKGxDdFV0bE5hbWVWYWx1ZSk7
DQoNCgkJbENyeXN0YWxSZXBvcnQuZ2VuZXJhdGVSZXBvcnQobGdEYXRhU291
cmNlTmFtZSwgbGdEYlNlcnZlck5hbWUsIGxnRGJVc2VyTmFtZSwNCgkJCQkJ
CQkJCWxnRGJVc2VyUGFzc3dvcmQsIGxnR2VuZXJhdGVkRmlsZUxvY2F0aW9u
LA0KCQkJCQkJCQkJbEN0UmVwRXhlY3V0aW9uUGFyYW1ldGVyVmFsdWVMTGlz
dCwNCgkJCQkJCQkJCWxDdFV0bE5hbWVWYWx1ZUxMaXN0VGVtcGxhdGVGaWxl
SW5mbywNCgkJCQkJCQkJCWxMTGlzdE91dHB1dEZvcm1hdHMNCgkJCQkJCQkJ
CSk7DQoNCg0KCX0NCg0KCXB1YmxpYyBib29sZWFuIGdlbmVyYXRlUmVwb3J0
KFN0cmluZyBpZ0RhdGFTb3VyY2VOYW1lDQoJCQkJCQkJLCBTdHJpbmcgaWdE
YlNlcnZlck5hbWUNCgkJCQkJCQksIFN0cmluZyBpZ0RiVXNlck5hbWUNCgkJ
CQkJCQksIFN0cmluZyBpZ0RiVXNlclBhc3N3b3JkDQoJCQkJCQkJLCBTdHJp
bmcgaWdHZW5lcmF0ZWRGaWxlTG9jYXRpb24NCgkJCQkJCQksIExpbmtlZExp
c3QgaUN0UmVwRXhlY3V0aW9uUGFyYW1ldGVyVmFsdWVMTGlzdA0KCQkJCQkJ
CSwgTGlua2VkTGlzdCBpQ3RVdGxOYW1lVmFsdWVMTGlzdFRlbXBsYXRlRmls
ZUluZm8NCgkJCQkJCQksIExpbmtlZExpc3QgaUxMaXN0T3V0cHV0Rm9ybWF0
cykgew0KDQoJCW9yZy5hcGFjaGUubG9nNGouUHJvcGVydHlDb25maWd1cmF0
b3IuY29uZmlndXJlKCJsb2c0ai5wcnAiKTsNCgkJb3JnLmFwYWNoZS5sb2c0
ai5DYXRlZ29yeSBsQ2F0ZWdvcnkgPSBvcmcuYXBhY2hlLmxvZzRqLkNhdGVn
b3J5LmdldEluc3RhbmNlKENyeXN0YWxSZXBvcnQuY2xhc3MuZ2V0TmFtZSgp
KTsNCgkJbENhdGVnb3J5LmluZm8oIlNUQVJUOjpnZW5lcmF0ZSBjcnlzdGFs
IFJlcG9ydCIpOw0KDQoJCWphdmEudXRpbC5IYXNoTWFwIGxITWFwUnVuVGlt
ZVVzZXJJbnB1dHMgPSBuZXcgamF2YS51dGlsLkhhc2hNYXAoKTsNCg0KCQkv
LyB0b2RvOiBOb3RlOg0KCQlmaW5hbCBTdHJpbmcgbGdEYXRlRm9ybWF0ID0g
ImRkL01NL3l5eXkiOw0KCQkvL2ZpbmFsIFN0cmluZyBsZ0RhdGVGb3JtYXQg
PSAiTU0gZGQseXl5eSI7DQoJCS8vZmluYWwgU3RyaW5nIGxnRGF0ZVRpbWVG
b3JtYXQgPSAiZGQvTU0veXl5eSBISDptbTpzcyI7DQoJCWZpbmFsIFN0cmlu
ZyBsZ0RhdGVUaW1lRm9ybWF0ID0gImRkL01NL3l5IEhIOm1tOnNzIjsNCgkJ
Ly95eXl5L01NL2RkIEhIOm1tOnNzDQoNCgkJT1JCIGxPUkJPYmo7DQoJCXRy
eSB7DQoNCgkJCS8vIHNldHRpbmcgdGhlIHByb3BlcnRpZXMgZm9yIGluaXRp
YWxpemF0aW9uLi4NCgkJCWxDYXRlZ29yeS5kZWJ1Zygic2V0dGluZyB0aGUg
cHJvcGVydGllcyBmb3IgaW5pdGlhbGl6YXRpb24uLiIpOw0KCQkJUHJvcGVy
dGllcyBsUHJvcGVydGllc09yYkluaXQgPSBuZXcgUHJvcGVydGllcygpOw0K
CQkJbFByb3BlcnRpZXNPcmJJbml0LnB1dCgib3JnLm9tZy5DT1JCQS5PUkJD
bGFzcyIsICJjb20uc3VuLkNPUkJBLmlpb3AuT1JCIik7DQoJCQlsUHJvcGVy
dGllc09yYkluaXQucHV0KCJvcmcub21nLkNPUkJBLk9SQlNpbmdsZXRvbkNs
YXNzIiwgImNvbS5zdW4uQ09SQkEuaWRsLk9SQlNpbmdsZXRvbiIpOw0KCQkJ
bFByb3BlcnRpZXNPcmJJbml0LnB1dCgib3JnLm9tZy5DT1JCQS5PUkJJbml0
aWFsSG9zdCIsIGdldE1nSG9zdE5hbWUoKSk7DQoJCQlsUHJvcGVydGllc09y
YkluaXQucHV0KCJvcmcub21nLkNPUkJBLk9SQkluaXRpYWxQb3J0IiwgZ2V0
TWdIb3N0UG9ydCgpKTsNCg0KCQkJbE9SQk9iaiA9IG9yZy5vbWcuQ09SQkFf
Ml8zLk9SQi5pbml0KChTdHJpbmdbXSludWxsLCBsUHJvcGVydGllc09yYklu
aXQpOw0KDQoJCQkvLyBnZXR0aW5nIGEgcmVmZXJlbmNlIHRvIHRoZSBuYW1p
bmcgY29udGV4dC4uDQoJCQlsQ2F0ZWdvcnkuZGVidWcoImdldHRpbmcgYSBy
ZWZlcmVuY2UgdG8gdGhlIG5hbWluZyBjb250ZXh0Li4iKTsNCgkJCW9yZy5v
bWcuQ29zTmFtaW5nLk5hbWluZ0NvbnRleHQgbE5hbWluZ0NvbnRleHRDdHgg
PQ0KCQkJCQlvcmcub21nLkNvc05hbWluZy5OYW1pbmdDb250ZXh0SGVscGVy
Lm5hcnJvdyhsT1JCT2JqLnJlc29sdmVfaW5pdGlhbF9yZWZlcmVuY2VzKCJO
YW1lU2VydmljZSIpKTsNCg0KCQkJLy8gcmV0cml2ZSBhIHJlZmVyZW5jZSB0
byB0aGUgcmVxdWlyZWQgQ09SQkEgb2JqZWN0Li4NCgkJCS8vICAgbiBidWls
ZCBhIG5hbWUgcmVmZXJlbmNlIGZvciByZXRyaWV2YWwuLg0KCQkJLy8gdG9k
bzogc2V0IHRoZSBmb2xsb3dpbmcgaW4gcmVzb3VyY2UgYnVuZGxlLi4NCgkJ
CWZpbmFsIFN0cmluZyBsZ09iamVjdElECT0gIkNyeXN0YWwiOw0KCQkJZmlu
YWwgU3RyaW5nIGxnT2JqZWN0CT0gIk9iamVjdCI7DQoNCgkJCW9yZy5vbWcu
Q29zTmFtaW5nLk5hbWVDb21wb25lbnQgbE5hbWVDb21wb25lbnRSb290ID0N
CgkJCQkJbmV3IG9yZy5vbWcuQ29zTmFtaW5nLk5hbWVDb21wb25lbnQobGdP
YmplY3RJRCwgbGdPYmplY3QpOw0KCQkJb3JnLm9tZy5Db3NOYW1pbmcuTmFt
ZUNvbXBvbmVudCBsTmFtZUNvbXBvbmVudENyeXN0YWxbXQk9IHtsTmFtZUNv
bXBvbmVudFJvb3R9Ow0KDQoJCQkvLyBmZXRjaCBhbmQgbmFycm93IHRoZSBy
ZWZlcmVuY2UgdG8gdGhlIGhlbHBlciBjbGFzcyBvZiB0aGUgQ09SQkEgb2Jq
ZWN0IHRvIGJlIGludm9rZWQuLg0KCQkJb3JnLm9tZy5DT1JCQS5PYmplY3Qg
bENPUkJBT2JqZWN0T2JqID0gbE5hbWluZ0NvbnRleHRDdHgucmVzb2x2ZShs
TmFtZUNvbXBvbmVudENyeXN0YWwpOw0KCQkJQ3RSZXBDb3JiYUNyeXN0YWxT
ZXJ2ZXIgbEN0UmVwQ29yYmFDcnlzdGFsU2VydmVyT2JqID0gQ3RSZXBDb3Ji
YUNyeXN0YWxTZXJ2ZXJIZWxwZXIubmFycm93KGxDT1JCQU9iamVjdE9iaik7
DQoJCQlpZiAobENhdGVnb3J5LmlzRGVidWdFbmFibGVkKCkpIHsNCgkJCQls
Q2F0ZWdvcnkuZGVidWcoImdvdCBhbmQgbmFycm93ZWQgdGhlIGhlbHBlciBj
bGFzcyByZWZlcmVuY2UuLiIpOw0KCQkJfSAvLyBpZg0KDQoNCgkJCS8vIC0t
IHByZXBhcmUgdGhlIHBhcmFtZXRlcnMgdG8gaW52b2tlIHRoZSBDT1JCQSBv
YmplY3QuLiAvLw0KCQkJZmluYWwgU3RyaW5nIGxnUmVwU2VydmVyTmFtZQkJ
CT0gIiI7DQoJCQlmaW5hbCBTdHJpbmcgbGdSZXBTZXJ2ZXJVc2VyTmFtZQkJ
PSAiIjsNCgkJCWZpbmFsIFN0cmluZyBsZ1JlcFNlcnZlclVzZXJQYXNzd29y
ZAk9ICIiOw0KCQkJZmluYWwgU3RyaW5nIGxnRmlsZUFjY2Vzc1ByZWZpeAkJ
CT0gIiI7DQoNCgkJCS8vIHNldCB1cCB0aGUgcmVwb3J0IHBhcmFtZXRlcnMu
Lg0KCQkJaW50IGxpRm9yQ291bnRlciA9IDA7DQoJCQlpbnQgbGlOb09mUGFy
YW1ldGVycyA9IGlDdFJlcEV4ZWN1dGlvblBhcmFtZXRlclZhbHVlTExpc3Qu
c2l6ZSgpOw0KCQkJQ3RSZXBDb3JiYVBhcmFtZXRlckluZm8gbEN0UmVwQ29y
YmFQYXJhbWV0ZXJJbmZvQXJyYXlbXSA9IG5ldyBDdFJlcENvcmJhUGFyYW1l
dGVySW5mb1tsaU5vT2ZQYXJhbWV0ZXJzXTsNCgkJCWphdmEudXRpbC5JdGVy
YXRvciBsSXRlcmF0b3JQYXJhbWV0ZXJzID0gaUN0UmVwRXhlY3V0aW9uUGFy
YW1ldGVyVmFsdWVMTGlzdC5pdGVyYXRvcigpOw0KDQoJCQlTdHJpbmcgbGdQ
YXJhbWV0ZXJDb2RlCT0gbnVsbDsNCgkJCWludCBsaVBhcmFtZXRlckRhdGFU
eXBlOw0KCQkJU3RyaW5nIGxnUGFyYW1ldGVyVmFsdWUJPSBudWxsOw0KCQkJ
U3RyaW5nIGxnUGFyYW1ldGVyRGF0YVR5cGUgPSBudWxsOw0KCQkJU3RyaW5n
IGxnVGFza0V4ZWN1dGlvbklEID0gbnVsbCA7DQoJCQlTdHJpbmcgbGdUYXNr
SUQgPSBudWxsIDsNCgkJCWxvbmcgbGxBdHRyaWJ1dGVJRCA9IDBMOw0KCQkJ
aW50IGxpRGF0YXR5cGUgPSAwOw0KDQoJCQlqYXZhLnV0aWwuSGFzaE1hcCBs
SE1hcFJlcVBhcmFtID0gbmV3IGphdmEudXRpbC5IYXNoTWFwKCkgOw0KCQkJ
Q3RSZXBFeGVjdXRpb25QYXJhbWV0ZXJJbmZvIGxDdFJlcEV4ZWN1dGlvblBh
cmFtZXRlckluZm89IG51bGwgOw0KCQkJQ3RSZXBDb3JiYVBhcmFtZXRlclZh
bHVlIGxDdFJlcENvcmJhUGFyYW1ldGVyVmFsdWVPYmoJPSBudWxsOw0KDQoJ
CQlsQ2F0ZWdvcnkuZGVidWcoImxvb3BpbmcgdGhydSBhbGwgdGhlIHBhcmFt
ZXRlcnMgdG8gY3JlYXRlIHRoZSBpbnB1dDogIiArIGxpTm9PZlBhcmFtZXRl
cnMpOw0KCQkJU3RyaW5nIGxnSG91ciA9ICBudWxsOw0KCQkJU3RyaW5nIGxn
TWludXRlID0gbnVsbDsNCg0KCQkJLy9kZWINCgkJCUN0UmVwQ29yYmFEYXRl
IGxDdFJlcENvcmJhRGF0ZSA9bnVsbDsNCgkJCS8vZGViDQoNCgkJCWZvciAo
bGlGb3JDb3VudGVyPTAgOyBsaUZvckNvdW50ZXI8bGlOb09mUGFyYW1ldGVy
cyA7IGxpRm9yQ291bnRlcisrKSB7DQoNCgkJCQlsQ3RSZXBFeGVjdXRpb25Q
YXJhbWV0ZXJJbmZvID0gbmV3IEN0UmVwRXhlY3V0aW9uUGFyYW1ldGVySW5m
bygpOw0KCQkJCWxDdFJlcEV4ZWN1dGlvblBhcmFtZXRlckluZm8gPQ0KCQkJ
CQkJKEN0UmVwRXhlY3V0aW9uUGFyYW1ldGVySW5mbylpQ3RSZXBFeGVjdXRp
b25QYXJhbWV0ZXJWYWx1ZUxMaXN0LmdldChsaUZvckNvdW50ZXIpOw0KDQoJ
CQkJLy8gdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIGN1cnJlbnQgRXhlY3V0aW9u
UGFyYW1ldGVyIG9iamVjdC4uDQoJCQkJbGdQYXJhbWV0ZXJDb2RlCQk9IGxD
dFJlcEV4ZWN1dGlvblBhcmFtZXRlckluZm8ubWdQYXJhbWV0ZXJDb2RlOw0K
CQkJCWxpUGFyYW1ldGVyRGF0YVR5cGUJPSBsQ3RSZXBFeGVjdXRpb25QYXJh
bWV0ZXJJbmZvLm1pUGFyYW1ldGVyRGF0YXR5cGU7DQoJCQkJbGdQYXJhbWV0
ZXJWYWx1ZQk9IGxDdFJlcEV4ZWN1dGlvblBhcmFtZXRlckluZm8ubWdQYXJh
bWV0ZXJWYWx1ZTsNCg0KCQkJCS8vIHRvZG86IHJlbW92ZSB0aGUgbG9nZ2lu
Zy4uDQoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJsZ1BhcmFtZXRlckNvZGU6
ICIgKyBsZ1BhcmFtZXRlckNvZGUpOw0KCQkJCVN5c3RlbS5vdXQucHJpbnRs
bigibGdQYXJhbWV0ZXJWYWx1ZTogIiArIGxnUGFyYW1ldGVyVmFsdWUpOw0K
DQoNCgkJCQlsQ3RSZXBDb3JiYVBhcmFtZXRlclZhbHVlT2JqID0gbmV3IEN0
UmVwQ29yYmFQYXJhbWV0ZXJWYWx1ZSgpOw0KCQkJCS8vIHNldHRpbmcgdGhl
IHBhcmFtZXRlciBkYXRhdHlwZSBuIGl0cyBhcHByb3ByaWF0dGUgdmFsdWUu
Lg0KCQkJCXN3aXRjaChsaVBhcmFtZXRlckRhdGFUeXBlKSB7DQoNCgkJCQlj
YXNlIEN0VXRsRGF0YVR5cGVFbnVtLkJPT0xFQU46IHsNCgkJCQkJbENhdGVn
b3J5LmRlYnVnKCJib29sZWFuIHZhbHVlIik7DQoJCQkJCWxDdFJlcENvcmJh
UGFyYW1ldGVyVmFsdWVPYmouc3RyaW5nVmFsKGxnUGFyYW1ldGVyVmFsdWUp
Ow0KCQkJCQlsZ1BhcmFtZXRlckRhdGFUeXBlID0gImJvb2xlYW4iOw0KCQkJ
CQlicmVhazsNCgkJCQl9IC8vIEJPT0xFQU4NCg0KCQkJCWNhc2UgQ3RVdGxE
YXRhVHlwZUVudW0uQ0hBUjogew0KCQkJCQlsQ2F0ZWdvcnkuZGVidWcoImNo
YXIgdmFsdWUiKTsNCgkJCQkJbEN0UmVwQ29yYmFQYXJhbWV0ZXJWYWx1ZU9i
ai5jaGFyVmFsKGxnUGFyYW1ldGVyVmFsdWUuY2hhckF0KDApKTsNCgkJCQkJ
bGdQYXJhbWV0ZXJEYXRhVHlwZSA9ICJjaGFyIjsNCgkJCQkJYnJlYWs7DQoJ
CQkJfSAvLyBDSEFSDQoNCgkJCQljYXNlIEN0VXRsRGF0YVR5cGVFbnVtLkJZ
VEU6DQoJCQkJY2FzZSBDdFV0bERhdGFUeXBlRW51bS5TSE9SVDoNCgkJCQlj
YXNlIEN0VXRsRGF0YVR5cGVFbnVtLklOVDoNCgkJCQljYXNlIEN0VXRsRGF0
YVR5cGVFbnVtLkxPTkc6DQoJCQkJY2FzZSBDdFV0bERhdGFUeXBlRW51bS5U
SU1FOg0KCQkJCXsNCg0KCQkJCQlsQ2F0ZWdvcnkuZGVidWcoImxvbmcgdmFs
dWUiKTsNCgkJCQkJbEN0UmVwQ29yYmFQYXJhbWV0ZXJWYWx1ZU9iai5sb25n
VmFsKG5ldyBJbnRlZ2VyKGxnUGFyYW1ldGVyVmFsdWUpLmludFZhbHVlKCkp
Ow0KCQkJCQlsZ1BhcmFtZXRlckRhdGFUeXBlID0gImxvbmciOw0KCQkJCQli
cmVhazsNCgkJCQl9IC8vDQoNCgkJCQljYXNlIEN0VXRsRGF0YVR5cGVFbnVt
LkRBVEU6IHsNCgkJCQkJU3lzdGVtLm91dC5wcmludGxuKCJpbnNpZGUgZGF0
ZSIpOw0KCQkJCQlsQ2F0ZWdvcnkuZGVidWcoImRhdGUgdmFsdWUiICsgbGdQ
YXJhbWV0ZXJWYWx1ZSk7DQoJCQkJCWxDYXRlZ29yeS5kZWJ1ZygiRGF0ZSBG
b3JtYXQ6ICIgKyBsZ0RhdGVGb3JtYXQpOw0KCQkJCQlDdFV0bERhdGVUaW1l
IGxDdFV0bERhdGVUaW1lID0gbnVsbDsNCgkJCQkJdHJ5IHsNCgkJCQkJCWxD
dFV0bERhdGVUaW1lID0gQ3RVdGxEYXRlVGltZS5jb252ZXJ0U3RyaW5nVG9E
YXRlKGxnUGFyYW1ldGVyVmFsdWUNCgkJCQkJCQkJCQkJCQkJCQkJCSwgbGdE
YXRlRm9ybWF0DQoJCQkJCQkJCQkJCQkJCQkJCQksIExvY2FsZS5nZXREZWZh
dWx0KCkpOw0KCQkJCQl9IGNhdGNoIChqYXZhLnRleHQuUGFyc2VFeGNlcHRp
b24gbFBhcnNlRXhjZXB0aW9uKSB7DQoJCQkJCQlsQ2F0ZWdvcnkuZmF0YWwo
IkV4Y2VwdGlvbjogIiArIGxQYXJzZUV4Y2VwdGlvbi50b1N0cmluZygpKTsN
Cg0KCQkJCQl9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbEls
bGVnYWxBcmd1bWVudEV4Y2VwdGlvbikgew0KCQkJCQkJbENhdGVnb3J5LmZh
dGFsKCJFeGNlcHRpb246ICIgKyBsSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9u
LnRvU3RyaW5nKCkpOw0KCQkJCQl9IC8vIHRyeS4uY2F0Y2gNCg0KCQkJCQlD
dFJlcENvcmJhRGF0ZSBsQ3RSZXBDb3JiYURhdGUgPSBuZXcgQ3RSZXBDb3Ji
YURhdGUoKTsNCgkJCQkJbEN0UmVwQ29yYmFEYXRlLnllYXIgPSBsQ3RVdGxE
YXRlVGltZS5nZXRZZWFyKCk7DQoJCQkJCWxDdFJlcENvcmJhRGF0ZS5tb250
aCA9IGxDdFV0bERhdGVUaW1lLmdldE1vbnRoT2ZZZWFyKCkgKyAxOw0KCQkJ
CQlsQ3RSZXBDb3JiYURhdGUuZGF5ID0gbEN0VXRsRGF0ZVRpbWUuZ2V0RGF5
KCk7DQoNCgkJCQkJbEN0UmVwQ29yYmFQYXJhbWV0ZXJWYWx1ZU9iai5DdFJl
cENvcmJhRGF0ZVZhbChsQ3RSZXBDb3JiYURhdGUpOw0KCQkJCQlsZ1BhcmFt
ZXRlckRhdGFUeXBlID0gImRhdGUiOw0KCQkJCQlicmVhazsNCgkJCQl9IC8v
IERBVEUNCg0KCQkJCWNhc2UgQ3RVdGxEYXRhVHlwZUVudW0uRE9VQkxFOg0K
CQkJCWNhc2UgQ3RVdGxEYXRhVHlwZUVudW0uRkxPQVQ6IHsNCgkJCQkJbENh
dGVnb3J5LmRlYnVnKCJkb3VibGUgdmFsdWUiKTsNCgkJCQkJbEN0UmVwQ29y
YmFQYXJhbWV0ZXJWYWx1ZU9iai5kb3VibGVWYWwobmV3IERvdWJsZShsZ1Bh
cmFtZXRlclZhbHVlKS5kb3VibGVWYWx1ZSgpKTsNCgkJCQkJbGdQYXJhbWV0
ZXJEYXRhVHlwZSA9ICJkb3VibGUiOw0KCQkJCQlicmVhazsNCgkJCQl9IC8v
IERPVUJMRS9GTE9BVA0KDQoJCQkJY2FzZSBDdFV0bERhdGFUeXBlRW51bS5T
VFJJTkc6DQoJCQkJCWxDYXRlZ29yeS5kZWJ1Zygic3RyaW5nIHZhbHVlIik7
DQoJCQkJCWxDdFJlcENvcmJhUGFyYW1ldGVyVmFsdWVPYmouc3RyaW5nVmFs
KGxnUGFyYW1ldGVyVmFsdWUpOw0KCQkJCQlsZ1BhcmFtZXRlckRhdGFUeXBl
ID0gInN0cmluZyI7DQoJCQkJCWJyZWFrOw0KDQoJLyoJCQljYXNlIEN0VXRs
RGF0YVR5cGVFbnVtLlRJTUU6IHsNCgkJCQkJU3lzdGVtLm91dC5wcmludGxu
KCJpbnNpZGUgdGltZSIpOw0KCQkJCQlsQ2F0ZWdvcnkuZGVidWcoInRpbWUg
dmFsdWUiKTsNCgkJCQkJQ3RSZXBDb3JiYURhdGUgbEN0UmVwQ29yYmFEYXRl
ID0gbmV3IEN0UmVwQ29yYmFEYXRlKCk7DQoJCQkJCWlmKGxnUGFyYW1ldGVy
VmFsdWUubGVuZ3RoKCk8NCl7DQoJCQkJCQlsQ3RSZXBDb3JiYURhdGUuaG91
ciA9IDA7DQoJCQkJCQlsQ3RSZXBDb3JiYURhdGUubWludXRlID0gMCA7DQoJ
CQkJCQlsQ3RSZXBDb3JiYURhdGUuc2Vjb25kID0gMDsNCgkJCQkJfWVsc2V7
DQoJCQkJCQlsZ0hvdXIgPSBsZ1BhcmFtZXRlclZhbHVlLnN1YnN0cmluZygw
LDIpIDsNCgkJCQkJCWxnTWludXRlID0gbGdQYXJhbWV0ZXJWYWx1ZS5zdWJz
dHJpbmcoMik7DQoJCQkJCQlsQ3RSZXBDb3JiYURhdGUuaG91ciA9IEludGVn
ZXIucGFyc2VJbnQobGdIb3VyKTsNCgkJCQkJCWxDdFJlcENvcmJhRGF0ZS5t
aW51dGUgPSBJbnRlZ2VyLnBhcnNlSW50KGxnTWludXRlKSA7DQoJCQkJCQls
Q3RSZXBDb3JiYURhdGUuc2Vjb25kID0gMDsNCgkJCQkJfQ0KDQoNCg0KDQoN
CgkJCQkJbEN0UmVwQ29yYmFQYXJhbWV0ZXJWYWx1ZU9iai5DdFJlcENvcmJh
RGF0ZVZhbChsQ3RSZXBDb3JiYURhdGUpOw0KCQkJCQlsZ1BhcmFtZXRlckRh
dGFUeXBlID0gInRpbWUiOw0KCQkJCQlicmVhazsNCgkJCQl9IC8vIFRJTUUN
CgkqLw0KDQoJCQkJY2FzZSBDdFV0bERhdGFUeXBlRW51bS5USU1FU1RBTVA6
IHsNCgkJCQkJbENhdGVnb3J5LmRlYnVnKCJ0aW1lc3RhbXAgdmFsdWUiKTsN
CgkJCQkJU3lzdGVtLm91dC5wcmludGxuKCJ0aW1lc3RhbXAgdmFsdWUgIik7
DQoJCQkJCUN0VXRsRGF0ZVRpbWUgbEN0VXRsRGF0ZVRpbWUgPSBudWxsOw0K
CQkJCQl0cnkgew0KCQkJCQkJbEN0VXRsRGF0ZVRpbWUgPSBDdFV0bERhdGVU
aW1lLmNvbnZlcnRTdHJpbmdUb0RhdGUobGdQYXJhbWV0ZXJWYWx1ZQ0KCQkJ
CQkJCQkJCQkJCQkJCQkJLCBsZ0RhdGVUaW1lRm9ybWF0DQoJCQkJCQkJCQkJ
CQkJCQkJCQksIExvY2FsZS5nZXREZWZhdWx0KCkpOw0KCQkJCQl9IGNhdGNo
IChqYXZhLnRleHQuUGFyc2VFeGNlcHRpb24gbFBhcnNlRXhjZXB0aW9uKSB7
DQoJCQkJCQlsQ2F0ZWdvcnkuZmF0YWwoIkV4Y2VwdGlvbjogIiArIGxQYXJz
ZUV4Y2VwdGlvbi50b1N0cmluZygpKTsNCg0KCQkJCQl9IGNhdGNoIChJbGxl
Z2FsQXJndW1lbnRFeGNlcHRpb24gbElsbGVnYWxBcmd1bWVudEV4Y2VwdGlv
bikgew0KCQkJCQkJbENhdGVnb3J5LmZhdGFsKCJFeGNlcHRpb246ICIgKyBs
SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLnRvU3RyaW5nKCkpOw0KCQkJCQl9
IC8vIHRyeS4uY2F0Y2gNCg0KCQkJCQkgbEN0UmVwQ29yYmFEYXRlID0gbmV3
IEN0UmVwQ29yYmFEYXRlKCk7DQoJCQkJCWxDdFJlcENvcmJhRGF0ZS55ZWFy
ID0gbEN0VXRsRGF0ZVRpbWUuZ2V0WWVhcigpOw0KCQkJCQlsQ3RSZXBDb3Ji
YURhdGUubW9udGggPSBsQ3RVdGxEYXRlVGltZS5nZXRNb250aE9mWWVhcigp
KzE7DQoJCQkJCWxDdFJlcENvcmJhRGF0ZS5kYXkgPSBsQ3RVdGxEYXRlVGlt
ZS5nZXREYXkoKTsNCgkJCQkJbEN0UmVwQ29yYmFEYXRlLmhvdXIgPSBsQ3RV
dGxEYXRlVGltZS5nZXRIb3VyKCk7DQoJCQkJCWxDdFJlcENvcmJhRGF0ZS5t
aW51dGUgPSBsQ3RVdGxEYXRlVGltZS5nZXRNaW51dGUoKTsNCgkJCQkJbEN0
UmVwQ29yYmFEYXRlLnNlY29uZCA9IGxDdFV0bERhdGVUaW1lLmdldFNlY29u
ZHMoKTsNCgkJCQkJbEN0UmVwQ29yYmFQYXJhbWV0ZXJWYWx1ZU9iai5DdFJl
cENvcmJhRGF0ZVZhbChsQ3RSZXBDb3JiYURhdGUpOw0KCQkJCQlTeXN0ZW0u
b3V0LnByaW50bG4oImxDdFJlcENvcmJhRGF0ZS55ZWFyOiAiICsgbEN0UmVw
Q29yYmFEYXRlLnllYXIpOw0KCQkJCQlTeXN0ZW0ub3V0LnByaW50bG4oImxD
dFJlcENvcmJhRGF0ZS5tb250aDogIiArIGxDdFJlcENvcmJhRGF0ZS5tb250
aCk7DQoJCQkJCVN5c3RlbS5vdXQucHJpbnRsbigibEN0UmVwQ29yYmFEYXRl
LmRheSIgKyBsQ3RSZXBDb3JiYURhdGUuZGF5KTsNCgkJCQkJU3lzdGVtLm91
dC5wcmludGxuKCJsQ3RSZXBDb3JiYURhdGUuaG91cjogIiArIGxDdFJlcENv
cmJhRGF0ZS5ob3VyKTsNCgkJCQkJU3lzdGVtLm91dC5wcmludGxuKCJsQ3RS
ZXBDb3JiYURhdGUubWludXRlIiArIGxDdFJlcENvcmJhRGF0ZS5taW51dGUp
Ow0KCQkJCQlTeXN0ZW0ub3V0LnByaW50bG4oImxDdFJlcENvcmJhRGF0ZS5z
ZWNvbmQ6ICIgKyBsQ3RSZXBDb3JiYURhdGUuc2Vjb25kKTsNCg0KCQkJCQls
Z1BhcmFtZXRlckRhdGFUeXBlID0gImRhdGV0aW1lIjsNCgkJCQkJYnJlYWs7
DQoJCQkJfSAvLyBUSU1FU1RBTVANCg0KCQkJCWRlZmF1bHQ6IHsNCg0KCQkJ
CQlTdHJpbmcgbGdFcnJvck1lc2cgPSAiaW52YWxpZCBkYXRhIHR5cGUgc3Bl
Y2lmaWVkISEiOw0KCQkJCQlsQ2F0ZWdvcnkuZGVidWcobGdFcnJvck1lc2cp
Ow0KCQkJCX0gLy8gZGVmYXVsdA0KDQoJCQkJfSAvLyBzd2l0Y2gNCg0KCQkJ
CS8vIHRvZG86IHJlbW92ZSB0aGUgbG9nZ2luZy4uDQoJCQkJU3lzdGVtLm91
dC5wcmludGxuKCJsZ1BhcmFtZXRlckNvZGU6ICIgKyBsZ1BhcmFtZXRlckNv
ZGUpOw0KDQoJCQkJbEN0UmVwQ29yYmFQYXJhbWV0ZXJJbmZvQXJyYXlbbGlG
b3JDb3VudGVyXSA9DQoJCQkJCQluZXcgQ3RSZXBDb3JiYVBhcmFtZXRlcklu
Zm8obGdQYXJhbWV0ZXJDb2RlDQoJCQkJCQkJCQkJCQksIGxnUGFyYW1ldGVy
RGF0YVR5cGUNCgkJCQkJCQkJCQkJCSwgbEN0UmVwQ29yYmFQYXJhbWV0ZXJW
YWx1ZU9iaik7DQoNCgkJCQkvLyBjbGVhbnVwIGZvciB0aGUgbmV4dCBpdGVy
YXRpb24uLg0KCQkJCWxnUGFyYW1ldGVyQ29kZQkJPSBudWxsOw0KCQkJCWxn
UGFyYW1ldGVyVmFsdWUJPSBudWxsOw0KCQkJCWxnUGFyYW1ldGVyRGF0YVR5
cGUgPSBudWxsOw0KCQkJCS8vZGViDQoJCQkJbEN0UmVwQ29yYmFQYXJhbWV0
ZXJWYWx1ZU9iaj1udWxsOw0KCQkJCS8vZGViDQoJCQl9IC8vIGZvcg0KDQoJ
CQkvLyBzZXQgdXAgdGhlIHRlbXBsYXRlIGZpbGUgaW5mby4uDQoJCQlsQ2F0
ZWdvcnkuZGVidWcoInRlbXBsYXRlIGZpbGUgc2V0dGluZ3MuLiIpOw0KCQkJ
aW50IGxpTm9PZlRlbXBsYXRlRmlsZXMgPSBpQ3RVdGxOYW1lVmFsdWVMTGlz
dFRlbXBsYXRlRmlsZUluZm8uc2l6ZSgpOw0KCQkJQ3RSZXBDb3JiYVRlbXBs
YXRlRmlsZUluZm8gbEN0UmVwQ29yYmFUZW1wbGF0ZUZpbGVJbmZvQXJyYXlb
XSA9IG5ldyBDdFJlcENvcmJhVGVtcGxhdGVGaWxlSW5mb1tsaU5vT2ZUZW1w
bGF0ZUZpbGVzXTsNCgkJCWphdmEudXRpbC5JdGVyYXRvciBsSXRlcmF0b3JU
ZW1wbGF0ZUZpbGVzID0gaUN0VXRsTmFtZVZhbHVlTExpc3RUZW1wbGF0ZUZp
bGVJbmZvLml0ZXJhdG9yKCk7DQoJCQlTdHJpbmcgbGdGaWxlTmFtZQkJPSBu
dWxsOw0KCQkJU3RyaW5nIGxnRmlsZUV4dGVuc2lvbgk9IG51bGw7DQoJCQlD
dFV0bE5hbWVWYWx1ZSBsQ3RVdGxOYW1lVmFsdWVGaWxlSW5mbyA9IG51bGw7
DQoNCgkJCWZvciAobGlGb3JDb3VudGVyPTAgOyBsaUZvckNvdW50ZXI8bGlO
b09mVGVtcGxhdGVGaWxlcyA7IGxpRm9yQ291bnRlcisrKSB7DQoNCgkJCQls
Q3RVdGxOYW1lVmFsdWVGaWxlSW5mbyA9IChDdFV0bE5hbWVWYWx1ZSlsSXRl
cmF0b3JUZW1wbGF0ZUZpbGVzLm5leHQoKTsNCg0KDQoJCQkJbGdGaWxlTmFt
ZQkJPSAoU3RyaW5nKSBsQ3RVdGxOYW1lVmFsdWVGaWxlSW5mby5tT2JqZWN0
TmFtZTsNCgkJCQlsZ0ZpbGVFeHRlbnNpb24JPSAoU3RyaW5nKWxDdFV0bE5h
bWVWYWx1ZUZpbGVJbmZvLm1PYmplY3RWYWx1ZTsNCg0KCQkJCWxDdFJlcENv
cmJhVGVtcGxhdGVGaWxlSW5mb0FycmF5W2xpRm9yQ291bnRlcl0gPQ0KCQkJ
CQkJbmV3IEN0UmVwQ29yYmFUZW1wbGF0ZUZpbGVJbmZvKGxnRmlsZU5hbWUs
IGxnRmlsZUV4dGVuc2lvbik7DQoNCgkJCX0gLy8gZm9yDQoNCgkJCS8vIHNl
dCB1cCB0aGUgb3V0cHV0IGZvcm1hdHMgaW5mby4uDQoJCQlsQ2F0ZWdvcnku
ZGVidWcoIm91dHB1dCBmb3JtYXRzLi4iKTsNCgkJCWludCBsaU5vT3V0cHV0
Rm9ybWF0cyA9IGlMTGlzdE91dHB1dEZvcm1hdHMuc2l6ZSgpOw0KCQkJaW50
IGxpT3V0cHV0Rm9ybWF0c1tdID0gbmV3IGludFtsaU5vT3V0cHV0Rm9ybWF0
c107DQoJCQlqYXZhLnV0aWwuSXRlcmF0b3IgbEl0ZXJhdG9yT3V0cHV0Rm9y
bWF0cyA9IGlMTGlzdE91dHB1dEZvcm1hdHMuaXRlcmF0b3IoKTsNCgkJCUlu
dGVnZXIgbElPdXRwdXRGb3JtYXQgPSBudWxsOw0KDQoJCQlmb3IgKGxpRm9y
Q291bnRlcj0wIDsgbGlGb3JDb3VudGVyPGxpTm9PdXRwdXRGb3JtYXRzIDsg
bGlGb3JDb3VudGVyKyspIHsNCg0KCQkJCWxJT3V0cHV0Rm9ybWF0ID0gKElu
dGVnZXIpbEl0ZXJhdG9yT3V0cHV0Rm9ybWF0cy5uZXh0KCkgOw0KCQkJCWxp
T3V0cHV0Rm9ybWF0c1tsaUZvckNvdW50ZXJdID0gbElPdXRwdXRGb3JtYXQu
aW50VmFsdWUoKTsNCg0KCQkJCS8vIHByZXBhcmluZyB0aGUgb2JqZWN0IGZv
ciB0aGUgbmV4dCBmbG93Li4NCgkJCQlsSU91dHB1dEZvcm1hdCA9IG51bGw7
DQoNCgkJCX0gLy8gZm9yDQoNCgkJCS8vIHNldCB1cCB0aGUgZXJyb3Igb3V0
cHV0IHBhcmFtZXRlci4uDQoJCQlDdFJlcENvcmJhRXJyb3JMaXN0SG9sZGVy
IG9DdFJlcENvcmJhRXJyb3JMaXN0RXJyb3JzID0gbmV3IEN0UmVwQ29yYmFF
cnJvckxpc3RIb2xkZXIoKTsNCg0KCQkJLy8gaW52b2tpbmcgdGhlIENPUkJB
IG9iamVjdC4uDQoNCgkJCS8vIFN0YXJ0OjpBbWFyZGVlcDogNC1EZWMtMDE6
IHRvZG86IHJlbW92ZQ0KCQkJQ3RSZXBDb3JiYVBhcmFtZXRlckluZm8gbEN0
UmVwQ29yYmFQYXJhbWV0ZXJJbmZvVGVzdCA9IG51bGw7DQoJCQlDdFJlcENv
cmJhUGFyYW1ldGVyVmFsdWUgbEN0UmVwQ29yYmFQYXJhbWV0ZXJWYWx1ZVRl
c3QgPSBudWxsOw0KCQkJZm9yIChpbnQgbGlDb3VudGVyID0gMDsgbGlDb3Vu
dGVyIDwgbGlOb09mUGFyYW1ldGVycyA7IGxpQ291bnRlcisrKSB7DQoNCgkJ
CQlsQ3RSZXBDb3JiYVBhcmFtZXRlckluZm9UZXN0ID0gbEN0UmVwQ29yYmFQ
YXJhbWV0ZXJJbmZvQXJyYXlbbGlDb3VudGVyXTsNCg0KCQkJCVN5c3RlbS5v
dXQucHJpbnRsbigibWdQYXJhbWV0ZXJOYW1lOiAiICsgbEN0UmVwQ29yYmFQ
YXJhbWV0ZXJJbmZvVGVzdC5tZ1BhcmFtZXRlck5hbWUpOw0KCQkJCVN5c3Rl
bS5vdXQucHJpbnRsbigibWdQYXJhbWV0ZXJEYXRhdHlwZTogIiArIGxDdFJl
cENvcmJhUGFyYW1ldGVySW5mb1Rlc3QubWdQYXJhbWV0ZXJEYXRhdHlwZSk7
DQoNCgkJCQlpZiAobEN0UmVwQ29yYmFQYXJhbWV0ZXJJbmZvVGVzdC5tZ1Bh
cmFtZXRlckRhdGF0eXBlLmVxdWFscygiZGF0ZXRpbWUiKSkgew0KCQkJCQls
Q3RSZXBDb3JiYVBhcmFtZXRlclZhbHVlVGVzdCA9IGxDdFJlcENvcmJhUGFy
YW1ldGVySW5mb1Rlc3QubUN0UmVwQ29yYmFQYXJhbWV0ZXJWYWx1ZUluZm87
DQoJCQkJCUN0UmVwQ29yYmFEYXRlIGxOZXdDdFJlcENvcmJhRGF0ZSA9IGxD
dFJlcENvcmJhUGFyYW1ldGVyVmFsdWVUZXN0LkN0UmVwQ29yYmFEYXRlVmFs
KCk7DQoJCQkJCVN5c3RlbS5vdXQucHJpbnRsbigibE5ld0N0UmVwQ29yYmFE
YXRlLnllYXI6ICIgKyBsTmV3Q3RSZXBDb3JiYURhdGUueWVhcik7DQoJCQkJ
CVN5c3RlbS5vdXQucHJpbnRsbigibE5ld0N0UmVwQ29yYmFEYXRlLm1vbnRo
OiAiICsgbE5ld0N0UmVwQ29yYmFEYXRlLm1vbnRoKTsNCgkJCQkJU3lzdGVt
Lm91dC5wcmludGxuKCJsTmV3Q3RSZXBDb3JiYURhdGUuZGF5IiArIGxOZXdD
dFJlcENvcmJhRGF0ZS5kYXkpOw0KCQkJCQlTeXN0ZW0ub3V0LnByaW50bG4o
ImxOZXdDdFJlcENvcmJhRGF0ZS5ob3VyOiAiICsgbE5ld0N0UmVwQ29yYmFE
YXRlLmhvdXIpOw0KCQkJCQlTeXN0ZW0ub3V0LnByaW50bG4oImxOZXdDdFJl
cENvcmJhRGF0ZS5taW51dGUiICsgbE5ld0N0UmVwQ29yYmFEYXRlLm1pbnV0
ZSk7DQoJCQkJCVN5c3RlbS5vdXQucHJpbnRsbigibE5ld0N0UmVwQ29yYmFE
YXRlLnNlY29uZDogIiArIGxOZXdDdFJlcENvcmJhRGF0ZS5zZWNvbmQpOw0K
CQkJCX0gLy8gaWYNCg0KCQkJfSAvLyBmb3INCg0KCQkJLy8gRW5kOjpBbWFy
DQoNCg0KCQkJbENhdGVnb3J5LmRlYnVnKCJpbnZva2luZyB0aGUgQ09SQkEg
b2JqZWN0Li4iKTsNCgkJCWJvb2xlYW4gbGJSZXN1bHQgPSBsQ3RSZXBDb3Ji
YUNyeXN0YWxTZXJ2ZXJPYmouZ2VuZXJhdGVSZXBvcnQoaWdEYXRhU291cmNl
TmFtZQ0KCQkJCQksIGlnRGJTZXJ2ZXJOYW1lLCBpZ0RiVXNlck5hbWUsIGln
RGJVc2VyUGFzc3dvcmQsIGxnUmVwU2VydmVyTmFtZQ0KCQkJCQksIGxnUmVw
U2VydmVyVXNlck5hbWUsIGxnUmVwU2VydmVyVXNlclBhc3N3b3JkICwgbGdG
aWxlQWNjZXNzUHJlZml4DQoJCQkJCSwgaWdHZW5lcmF0ZWRGaWxlTG9jYXRp
b24sIGxDdFJlcENvcmJhUGFyYW1ldGVySW5mb0FycmF5DQoJCQkJCSwgbEN0
UmVwQ29yYmFUZW1wbGF0ZUZpbGVJbmZvQXJyYXksIGxpT3V0cHV0Rm9ybWF0
cywgb0N0UmVwQ29yYmFFcnJvckxpc3RFcnJvcnMpOw0KDQoJCQlsQ2F0ZWdv
cnkuZGVidWcoIlJlc3VsdCBvZiB0aGUgY2FsbDogIiArIGxiUmVzdWx0KTsN
CgkJCWlmIChsYlJlc3VsdCkgew0KCQkJCXJldHVybiB0cnVlOw0KCQkJfSBl
bHNlIHsNCgkJCQlyZXR1cm4gZmFsc2U7DQoJCQl9IC8vIGlmLmVsc2UNCg0K
DQoJCX0gY2F0Y2goRXhjZXB0aW9uIGUpIHsNCgkJCWxDYXRlZ29yeS5mYXRh
bCgiRXhjZXB0aW9uOiAiICsgZSk7DQoJCX0gZmluYWxseSB7DQoNCgkJfSAv
LyB0cnkuLmNhdGNoLi5maW5hbGx5DQoNCgkJbENhdGVnb3J5LmluZm8oIkVO
RDo6Z2VuZXJhdGVSZXBvcnQiKTsNCgkJcmV0dXJuIHRydWU7DQoNCgl9IC8v
IGdlbmVyYXRlUmVwb3J0KCkNCg0KCXB1YmxpYyBTdHJpbmcgZ2V0TWdIb3N0
TmFtZSgpDQoJew0KCQlTeXN0ZW0ub3V0LnByaW50bG4oIklORk86Om1nSG9z
dE5hbWUiICsgbWdIb3N0TmFtZSk7DQoJCXJldHVybiBtZ0hvc3ROYW1lOw0K
CX0NCg0KCXB1YmxpYyBTdHJpbmcgZ2V0TWdIb3N0UG9ydCgpDQoJew0KCQlT
eXN0ZW0ub3V0LnByaW50bG4oIklORk86Om1nSG9zdFBvcnQiICsgbWdIb3N0
UG9ydCk7DQoJCXJldHVybiBtZ0hvc3RQb3J0Ow0KCX0NCn0gLy8gZW5kIGNs
YXNzDQo=
--0-126301472-1007495304=:37530--