/*****************************************************************************/
/*                                                                           */
/*                                                                           */
/*   ©Copyright  2009 – 2012 BMC Software, Inc.                              */
/*   BMC, BMC Software, the BMC logos and other BMC marks are trademarks or  */
/*   registered trademarks of BMC Software, Inc. in the U.S. and /or         */
/*   certain other countries.                                                */
/*****************************************************************************/

package com.bmc.arsys.demo.javadriver;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.TreeMap;

import com.bmc.arsys.api.*;

public class InputReader {

    static Stack<Object> inputSources = new Stack<Object>();
    static BufferedReader currentInputSource = new BufferedReader(new InputStreamReader(System.in));
    static boolean nullPromptOption = false;

    public static void setNullPromptOption(boolean value) {
        nullPromptOption = value;
    }

    public static boolean getNullPromptOption() {
        return nullPromptOption;
    }

    public static void getInputLine() throws IOException {

        String inputLine = null;
        ThreadControlBlock threadControlBlockPtr = JavaDriver.getThreadControlBlockPtr();
        BufferedReader currentInputFile = threadControlBlockPtr.getCurrentInputFile();

        inputLine = currentInputFile.readLine();

        if (inputLine == null) /* EOF: Print error and exit */
        {
            if (threadControlBlockPtr.isCurrentInputSourceStdInput()) {
                JavaDriver.outputWriter.driverPrintError("\n*** EOF on input file; exiting ***\n");
                System.exit(1);
            }
            // Nested file; return to previous 
            threadControlBlockPtr.closeCurrentInputFile();
            getInputLine();
            return;
        }

        threadControlBlockPtr.addToCurrentInputFilePosition(inputLine.length());

        /* record command if recording is active */
        PrintWriter fp = threadControlBlockPtr.getRecordFile();

        if (fp != null) {
            if (!inputLine.equals("srec")) {
                fp.write(inputLine);
                fp.write("\n");
            }
        }

        /* Remove any trailing white spaces */
        int index = 0;
        for (index = inputLine.length() - 1; index >= 0; index--) {
            if ((inputLine.charAt(index) != ' ') || (inputLine.charAt(index) != '\t')
                    || (inputLine.charAt(index) != '\n')) {
                break;
            }
        }

        threadControlBlockPtr.setBuffer(inputLine.substring(0, index + 1));

        /* Process if it is a comment */
        if ((inputLine.length() >= 1) && (inputLine.charAt(0) == '#')) {
            if (threadControlBlockPtr.processCommentLine(inputLine) && (threadControlBlockPtr.getIsStdOut() == false)) {
                JavaDriver.outputWriter.printResult(inputLine + "\n");
            }
        }

        return;
    }

    public static boolean getBoolean(String prompt, boolean defaultVal) throws IOException {

        if (!getNullPromptOption()) {
            return defaultVal;
        }
        return getBooleanForChangingInfo(prompt, defaultVal);
    }

    public static boolean getBooleanForChangingInfo(String prompt, boolean defaultVal) throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt(prompt);

        boolean val = defaultVal;
        getInputLine();

        ThreadControlBlock threadControlBlockPtr = JavaDriver.getThreadControlBlockPtr();
        String input = threadControlBlockPtr.getBuffer();

        if (input.length() != 0) {
            if (input.equals("t") || input.equals("true") || input.equals("T")) {
                val = true;
            } else {
                val = false;
            }
        }

        return val;
    }

    public static int getInt(int defaultVal) throws IOException {

        getInputLine();
        ThreadControlBlock threadControlBlockPtr = JavaDriver.getThreadControlBlockPtr();
        String input = threadControlBlockPtr.getBuffer();

        int value = defaultVal;

        if (input.length() != 0) {
            try {
                Integer val = new Integer(input);
                value = val.intValue();
            } catch (NumberFormatException e) {
                // Do nothing
            }
        }
        return value;
    }

    public static int getInt(String prompt, int defaultVal) throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt(prompt);

        return getInt(defaultVal);
    }

    public static long getLong(String prompt, long defaultVal) throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt(prompt);

        long value = defaultVal;
        getInputLine();

        ThreadControlBlock threadControlBlockPtr = JavaDriver.getThreadControlBlockPtr();
        String input = threadControlBlockPtr.getBuffer();

        if (input.length() != 0) {
            try {
                Long val = new Long(input);
                value = val.longValue();
            } catch (NumberFormatException e) {
                // Do nothing
            }
        }

        return value;
    }

    public static double getDouble(String prompt, double defaultVal) throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt(prompt);

        double value = defaultVal;
        getInputLine();

        ThreadControlBlock threadControlBlockPtr = JavaDriver.getThreadControlBlockPtr();
        String input = threadControlBlockPtr.getBuffer();

        if (input.length() != 0) {
            try {
                Double val = new Double(input);
                value = val.doubleValue();
            } catch (NumberFormatException e) {
                // Do nothing
            }
        }
        return value;
    }

    public static char getChar(String prompt, char defaultVal) throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt(prompt);

        char value = defaultVal;
        getInputLine();

        ThreadControlBlock threadControlBlockPtr = JavaDriver.getThreadControlBlockPtr();
        String input = threadControlBlockPtr.getBuffer();

        if (input.length() != 0) {
            value = input.charAt(0);
        }

        return value;
    }

    public static String getString(String prompt, String defaultVal) throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt(prompt);
        getInputLine();

        ThreadControlBlock threadControlBlockPtr = JavaDriver.getThreadControlBlockPtr();
        String value = threadControlBlockPtr.getBuffer();

        if ((value == null) || (value.length() == 0)) {
            return defaultVal;
        }

        ARServerUser tmpContext = threadControlBlockPtr.getContext();

        if (tmpContext != null) {
            if (value.equals("$USER$")) {
                if (tmpContext.getUser() != null) {
                    threadControlBlockPtr.setBuffer(tmpContext.getUser());
                }
            }

            if (value.equals("$SERVER$")) {
                threadControlBlockPtr.setBuffer(tmpContext.getServer());
            }

            if (value.equals("$FIRST_LIST_ID$")) {
                threadControlBlockPtr.setBuffer(threadControlBlockPtr.getFirstListId());
            }

            if (value.equals("$SECOND_LIST_ID$")) {
                threadControlBlockPtr.setBuffer(threadControlBlockPtr.getSecondListId());
            }

            if (value.equals("$LAST_LIST_ID$")) {
                threadControlBlockPtr.setBuffer(threadControlBlockPtr.getLastListId());
            }
        }

        value = threadControlBlockPtr.getBuffer();
        if ((value == null) || (value.length() == 0)) {
            return defaultVal;
        }
        return value;
    }

    public static Time getTimeOfDay(String prompt, Time defaultTime) throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt(prompt + "(" + defaultTime.getValue() + "): ");

        Time timeOfDay = new Time(defaultTime.getValue());

        getInputLine();
        ThreadControlBlock threadControlBlockPtr = JavaDriver.getThreadControlBlockPtr();
        String s = threadControlBlockPtr.getBuffer();

        if (s.length() != 0) {
            Long val = new Long(s);
            timeOfDay.setValue(val.longValue());
        }
        return timeOfDay;
    }

    public static Timestamp getTimestamp(String prompt, Timestamp defaultTime) throws IOException {

        if (getBoolean("Null Timestamp (F): ", false)) {
            return null;
        }

        String input = getString(prompt, "");

        Timestamp time = new Timestamp(defaultTime.getValue());

        if (input.length() != 0) {
            Long val = new Long(input);
            time.setValue(val.longValue());
        }

        return time;
    }

    public static Timestamp[] getTimestampArray() throws IOException {

        Timestamp[] timestampList = null;
        int numItems = getInt("Number of Timestamps (0): ", 0);

        if (numItems != 0) {
            timestampList = new Timestamp[numItems];
            for (int i = 0; i < numItems; i++) {
                timestampList[i] = getTimestamp("   Timestamp: (0)", new Timestamp(0));
            }
        }

        return timestampList;
    }

    public static List<Timestamp> getTimestampList() throws IOException {
        Timestamp[] array = getTimestampArray();
        return new ArrayList<Timestamp>(java.util.Arrays.asList(array));
    }

    public static int[] getInternalIDList() throws IOException {

        int[] idList = null;

        int numItems = getInt("  Number of ids( 0 ): ", 0);

        if (numItems != 0) {
            idList = new int[numItems];
            for (int i = 0; i < numItems; i++) {
                idList[i] = getInt("    Id  " + i + " ( 1 ): ", 1);
            }
        }

        return idList;
    }
    
    public static List<Integer> getInternalIDArrayList() throws IOException {

        List<Integer> idList = new ArrayList<Integer>();

        int numItems = getInt("  Number of ids( 0 ): ", 0);

        if (numItems != 0) {
            for (int i = 0; i < numItems; i++) {
                idList.add(getInt("    Id  " + i + " ( 1 ): ", 1));
            }
        }

        return idList;
    }

    public static List<Integer> getIntegerList() throws IOException {

        List<Integer> list = new ArrayList<Integer>();

        int numItems = getInt("  Number of ids( 0 ): ", 0);

        if (numItems != 0) {
            for (int i = 0; i < numItems; i++) {
                list.add(new Integer(getInt("    Id  " + i + " ( 1 ): ", 1)));
            }
        }

        return list;
    }

    public static FormType[] getFormTypeList() throws IOException {

        FormType[] formTypeList = null;

        int numItems = getInt("  Number of  Values( 0 ): ", 0);

        if (numItems != 0) {
            formTypeList = new FormType[numItems];

            for (int i = 0; i < numItems; i++) {
                formTypeList[i] = getFormType();
            }
        }

        return formTypeList;
    }

    public static String[] getStringArray(String indent, String header) throws IOException {

        String[] nameList = null;

		if (header == null || header.length() == 0)
			header = "item";
        int numItems = getInt(indent + "Number of " + header + "s (0): ", 0);
        if (numItems != 0) {
            nameList = new String[numItems];

            for (int i = 0; i < numItems; i++) {
                nameList[i] = getString(indent + header + "(" + i + "): ", "");
            }
        }

        return nameList;
    }

    public static List<String> getStringList(String indent, String header) throws IOException {
        String[] array = getStringArray(indent, header);
        if (array != null)
            return new ArrayList<String>(java.util.Arrays.asList(array));

        return null;
    }

    public static String[] getApplicationKeyList(String indent) throws IOException {

        String[] nameList = null;

        int numItems = getInt(indent + "Number of application keys (0): ", 0);
        if (numItems != 0) {
            nameList = new String[numItems];

            for (int i = 0; i < numItems; i++) {
                nameList[i] = getString(indent + "Name " + "(" + i + "): ", "");
            }
        }

        return nameList;
    }

    public static void getARServerUser() throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("Control record:\n");

        ThreadControlBlock threadControlBlockPtr = JavaDriver.getThreadControlBlockPtr();

        ARServerUser serverUser = threadControlBlockPtr.getContext();
        String authentication = null;
        if ((serverUser.getAuthentication() != null)) {
            authentication = getString("   Authentication String (" + serverUser.getAuthentication() + "): ",
                    serverUser.getAuthentication());
        } else {
            authentication = getString("   Authentication String (): ", "");
        }

        serverUser.setAuthentication(authentication);

        String name = null;

        if ((serverUser.getUser() != null) && (serverUser.getUser() != null)) {
            name = getString("   User name (" + serverUser.getUser() + "): ", serverUser.getUser());
        } else {
            name = getString("   User name (): ", "");
        }

        serverUser.setUser(name);
        String password = null;

        if ((serverUser.getPassword() != null) && (serverUser.getPassword() != null)) {
            password = getString("   Password (" + serverUser.getPassword() + "): ", serverUser.getPassword());
        } else {
            password = getString("   Password(): ", "");
        }

        serverUser.setPassword(password);

        String localeStr = null;
        LocaleCharSet localeCharSet = new LocaleCharSet();
        if (serverUser.getLocale() != null) {
            localeCharSet.setLocale(serverUser.getLocale());
            String dispStr = localeCharSet.toString();
            localeStr = getString("   Locale (" + dispStr + "): ", dispStr);
        } else {
            localeStr = getString("   Locale : ", "");
        }
        localeCharSet.parseLocaleAndCharSet(localeStr);
        serverUser.setLocale(localeCharSet.getLocale());

        String timeZone = null;

        if (serverUser.getTimeZone() != null) {
            timeZone = getString("   TimeZone (" + serverUser.getTimeZone() + "): ", serverUser.getTimeZone());
        } else {
            timeZone = getString("   TimeZone () : ", "");
        }

        serverUser.setTimeZone(timeZone);

        String server = null;

        if (serverUser.getServer() != null) {
            server = getString("   Server (" + serverUser.getServer() + "): ", serverUser.getServer());
        } else {
            server = getString("   Server () : ", "");
        }

        serverUser.setServer(server);

    }

    public static FilterMessageAction getFilterStatusInfo() throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("Status Info:\n");

        if (getBoolean("Null Filter Status Info (F): ", false)) {
            return null;
        }

        int messageType = getInt("   Note, Warning, or Error (0, 1, 2) (2) : ", 2);
        int messageNumber = getInt("   Message number (0): ", 0);
        String messageText = getString("   Message Text():  ", "");

        return new FilterMessageAction(messageType, messageNumber, messageText);
    }

    public static MessageAction getMessageInfo() throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("Message Info:\n");

        if (getBoolean("Null Message Info (F): ", false)) {
            return null;
        }

        int messageType = getInt("   Note, Warning, Error, Prompt, Accessible hint or Tooltip (0, 1, 2, 5, 6, 7)(2) : ", 2);
        int messageNumber = getInt("   Message number (10000): ", 10000);
        String messageText = getString("   Message Text():  ", "");
        boolean usePane = getBooleanForChangingInfo("   Use Prompting Pane? (T): ", true);

        return new MessageAction(messageType, messageNumber, messageText, usePane);
    }

    public static List<CoordinateInfo> getCoordinateInfoList() throws IOException {

        List<CoordinateInfo> coordinates = null;

        int numberOfItems = getInt("Number of Items in the List (0): ", 0);

        if (numberOfItems != 0) {
            coordinates = new ArrayList<CoordinateInfo>(numberOfItems);

            int i;
            int x;
            int y;

            for (i = 0; i < numberOfItems; i++) {
                x = getInt("x (" + i + "): ", 0);
                y = getInt("y (" + i + "): ", 0);

                coordinates.add(new CoordinateInfo(x, y));
            }
        }

        return coordinates;
    }

    public static ByteListValue getByteListInfo() throws IOException {

        if (getBoolean("Null ByteListInfo (F): ", false)) {
            return null;
        }

        byte[] byteArray = null;

        int type = getInt("Byte List Type (0): ", 0);
        int numberOfBytes = getInt("Number of Items in the List (0): ", 0);

        if (numberOfBytes != 0) {
            byteArray = new byte[numberOfBytes];
            for (int i = 0; i < numberOfBytes; i++) {
                byteArray[i] = (byte) getChar("Byte (" + i + "): ", '0');
            }
        }

        return new ByteListValue(type, byteArray);
    }

    public static AttachmentValue getAttachmentInfo() throws IOException {

        if (getBoolean("Null AttachmentInfo (F): ", false)) {
            return null;
        }

        String name = getString("Attachment Name(): ", "");

        int choice = getInt("Choose:\n" + "   1 - prompt for filename,\n" + "   2 - prompt for string\n"
                + "   default (1): ", 1);

        if ((choice < 1) || (choice > 2)) {
            JavaDriver.outputWriter
                    .driverPrintWarning("   ERROR: choice outside range 1-4; defaulting to prompt for filename(1)");
            choice = 1;
        }

        if (choice == 1) {
            String cname = null;

            if (getBoolean("Null FileName? (F):", false) == false) {
                cname = getString("File Name ():", "");
            }

            File fp = new File(cname);
            if (fp.exists() && fp.canRead()) {
                return new AttachmentValue(name, cname);
            } else {
                JavaDriver.outputWriter.driverPrintError("  ERROR: failed to open file\n");
                return null;
            }
        } else {
            String content = getString("Enter String(): ", "");
            return new AttachmentValue(name, content.getBytes());
        }
    }

    public static Value getValue() throws IOException, ARException {
        return getValue("");
    }
    
    public static Value getValue(String indent) throws IOException, ARException {

        if (getBoolean(indent + "Null Value (F): ", false)) {
            return null;
        }

        int dataType;
        
        if(indent == "") {
        	dataType = getInt(
                "Datatype Null/Key/Int/Real/Char/DiaryList/Enum/Time/Bitmask/Byte\n    Decimal/attach/currency/date/timeofday/join/trim/control/Table/Column/ulong/coords/view/display (0 - 14, 30-34, 40-43) (0): ",
                0);
        }
        else {
        	dataType = getInt(indent + 
                "Datatype Null/Key/Int/Real/Char/DiaryList/Enum/Time/Bitmask/Byte/Decimal/attach/currency/date/timeofday/join/trim/control/Table/Column/ulong/coords/view/display (0 - 14, 30-34, 40-43) (0): ",
                0);        	
        }

        Value val = getValue(dataType, indent);

        return val;
    }

    public static Value getValue(int dataType) throws IOException, ARException {
    	return getValue(dataType, "");
    }
    
    public static Value getValue(int dataType, String indent) throws IOException, ARException {

        Value val = null;
        switch (dataType) {
        case Constants.AR_DATA_TYPE_NULL:
            val = new Value();
            break;

        case Constants.AR_DATA_TYPE_KEYWORD:
            int keycode = getInt(indent + "Keyword Code (0): ", 0);
            val = new Value(Keyword.toKeyword(keycode));
            break;

        case Constants.AR_DATA_TYPE_INTEGER:
            int intVal = getInt(indent + "Integer Value (0): ", 0);
            val = new Value(intVal);
            break;

        case Constants.AR_DATA_TYPE_REAL:
            double doubleVal = (double) getDouble(indent + "Real Value (0.0): ", (double) 0.0);
            val = new Value(doubleVal);
            break;

        case Constants.AR_DATA_TYPE_CHAR:
            String name = getString(indent + "Char Value (): ", "");
            val = new Value(name);
            break;

        case Constants.AR_DATA_TYPE_DIARY:
            String dairyValue = getString(indent + "DiaryList Value (): ", "");
            DiaryListValue diaryList = new DiaryListValue();
            diaryList.setAppendedText(dairyValue);
            val = new Value(diaryList);
            break;

        case Constants.AR_DATA_TYPE_ENUM:
            int enumVal = getInt(indent + "Enum Value( 0 ): ", 0);
            val = new Value(enumVal, DataType.ENUM);
            break;

        case Constants.AR_DATA_TYPE_TIME:
            Timestamp timeStamp = getTimestamp(indent + "Time Value (0):", new Timestamp(0));
            val = new Value(timeStamp);
            break;
        case Constants.AR_DATA_TYPE_TIME_OF_DAY:
            Time timeOfDay = getTimeOfDay(indent + "Time Of Day Value(0):", new Time(0));
            val = new Value(timeOfDay);
            break;

        case Constants.AR_DATA_TYPE_BITMASK:
            long maskVal = getLong("indent + Bitmask Value (0): ", 0);
            val = new Value(maskVal, DataType.BITMASK);
            break;

        case Constants.AR_DATA_TYPE_BYTES:
            ByteListValue byteList = getByteListInfo();
            val = new Value(byteList);
            break;

        case Constants.AR_DATA_TYPE_JOIN:
            val = new Value(null, DataType.JOIN);
            break;

        case Constants.AR_DATA_TYPE_TRIM:
            val = new Value(null, DataType.TRIM);
            break;

        case Constants.AR_DATA_TYPE_CONTROL:
            val = new Value(null, DataType.CONTROL);
            break;

        case Constants.AR_DATA_TYPE_PAGE:
            val = new Value(null, DataType.PAGE);
            break;

        case Constants.AR_DATA_TYPE_PAGE_HOLDER:
            val = new Value(null, DataType.PAGE_HOLDER);
            break;

        case Constants.AR_DATA_TYPE_ATTACH_POOL:
            val = new Value(null, DataType.ATTACHMENT_POOL);
            break;

        case Constants.AR_DATA_TYPE_ULONG:
            long ulongVal = getLong("indent + Ulong Value (0): ", 0);
            val = new Value(ulongVal, DataType.ULONG);
            break;

        case Constants.AR_DATA_TYPE_COORDS:
            List<CoordinateInfo> coords = getCoordinateInfoList();
            val = new Value(coords);
            break;

        case Constants.AR_DATA_TYPE_ATTACH:
            AttachmentValue attach = getAttachmentInfo();
            val = new Value(attach);
            break;

        case Constants.AR_DATA_TYPE_DECIMAL:
            String decimalString = getString(indent + "Decimal Value ():", "");
            checkDecimalFormat(decimalString);
            BigDecimal decimalValue = new BigDecimal(decimalString);
            val = new Value(decimalValue);
            break;

        case Constants.AR_DATA_TYPE_CURRENCY:
            String value = getString(indent + "Value (0.0):", "");
            checkDecimalFormat(value);
            String currencyCode = getString(indent + "CurrencyCode (USD):", "USD");
            Timestamp conversionDate = getTimestamp(indent + "Conversion Date (0):", new Timestamp(0));
            CurrencyValue currencyInfo = new CurrencyValue(value, currencyCode, conversionDate, null);
            val = new Value(currencyInfo);
            break;

        case Constants.AR_DATA_TYPE_VIEW:
            String view = getString(indent + "View Value (): ", "");
            val = new Value(view, DataType.VIEW);
            break;

        case Constants.AR_DATA_TYPE_DISPLAY:
            String display = getString(indent + "Display Value (): ", "");
            val = new Value(display, DataType.DISPLAY);
            break;

        case Constants.AR_DATA_TYPE_DATE:
            String date = getString(indent + "Date Value ()[YYYY-MM-DD]: ", "");
            val = new Value(new DateInfo(DateInfo.dateToJulianDate("yyyy-MM-dd", date)), DataType.DATE);
            break;
        default:
            break;
        }

        return val;
    }

    static public List<Value> getValueList() throws IOException, ARException {

        List<Value> valueList = null;

        int numberOfValues = getInt("   Number of values (0): ", 0);

        if (numberOfValues != 0) {
            valueList = new ArrayList<Value>(numberOfValues);
            for (int i = 0; i < numberOfValues; i++) {
                valueList.add(getValue());
            }
        }

        return valueList;
    }

    static public EntryListFieldInfo getEntryListFieldInfo() throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("   Entry list field Info\n");

        if (getBoolean("Null EntryListFieldInfo (F): ", false)) {
            return null;
        }

        int fieldId = getInt("      Field id (0): ", 0);

        int columnWidth = getInt("      Column width (20): ", 20);

        String separator = getString("      Separator(  ): ", "  ");

        return new EntryListFieldInfo(fieldId, columnWidth, separator);
    }

    public static List<EntryListFieldInfo> getEntryListFieldInfoList() throws IOException {
        List<EntryListFieldInfo> entryListFieldList = null;

        int numItems = getInt("Number of  query list fields (0): ", 0);

        if (numItems != 0) {
            entryListFieldList = new ArrayList<EntryListFieldInfo>(numItems);
            for (int i = 0; i < numItems; i++) {
                entryListFieldList.add(getEntryListFieldInfo());
            }
        }

        return entryListFieldList;
    }

    public static StatusHistoryValueIndicator getStatusHistoryValue() throws IOException {

        if (getBoolean("Null StatusHistoryValue (F): ", false)) {
            return null;
        }

        int index = getInt("Enumerated value index (0): ", 0);
        int userOrTime = getInt("User or Time field (1 or 2) (2): ", 2);

        boolean type = true;

        if (userOrTime == 2) {
            type = false;
        }

        return new StatusHistoryValueIndicator(type, index);
    }

    public static CurrencyPartInfo getCurrencyPartInfo() throws IOException {

        int id = getInt("Currency Field Id (0): ", 0);
        int partTag = getInt("Currency Part - Field,Value,Type,Date,Functional (0-4) (0): ", 0);
        String currencyCode = null;

        if (partTag == Constants.AR_CURRENCY_PART_FUNCTIONAL) {
            currencyCode = getString("Functional currency code:", "");
        }

        return new CurrencyPartInfo(id, partTag, currencyCode);
    }

    public static ArithmeticOrRelationalOperand getArithmeticOrRelationalOperand(List<IQuerySource> fieldSources,
    		String indent) throws IOException, ARException {

        if (getBoolean("Null ArithmeticOrRelationalOperand (F): ", false)) {
            return null;
        }

        OperandType opType = null;
        
        boolean promptSources = (fieldSources != null && fieldSources.size() > 0);

        int operation;
        if(!promptSources) {
        	operation = getInt( 
                "Fld,Value,Arith,Stat-Hist,Val-Set,Currency,Fld-Tran,Fld-DB,L-Var,\nQuery,Currency-Tran,Currency-DB,Currency-Current,Fld-Current (1-6,50-56,99): ",
                0);
        }
        else {
        	operation = getInt(
                    "Fld,Value,Arith,Stat-Hist,Val-Set,Currency,Val-Set Query,Fld-Tran,Fld-DB,L-Var,Query,Currency-Tran,Currency-DB,Currency-Current,Fld-Current (1-7,50-56,99): ",
                    0);
        }

        ArithmeticOrRelationalOperand arithOrRlOperand = null;
        opType = OperandType.getOperandType(operation);
        switch (operation) {
        case Constants.AR_FIELD:
        case Constants.AR_FIELD_TRAN:
        case Constants.AR_FIELD_DB:
        case Constants.AR_FIELD_CURRENT:
        	if(promptSources) {        		        		
        		arithOrRlOperand = new ArithmeticOrRelationalOperand(getQueryFormField(fieldSources, indent));
        	}
        	else {
        		int fldId = getInt(indent + "Field id (0): ", 0);
        		arithOrRlOperand = new ArithmeticOrRelationalOperand(opType, fldId);        		
        	}
            break;

        case Constants.AR_VALUE:
            Value val = getValue(indent);
            arithOrRlOperand = new ArithmeticOrRelationalOperand(val);
            break;

        case Constants.AR_ARITHMETIC:
            ArithmeticOperationInfo aropInfo = getArithmeticOperationInfo(indent);
            arithOrRlOperand = new ArithmeticOrRelationalOperand(aropInfo);
            break;

        case Constants.AR_STAT_HISTORY:
            StatusHistoryValueIndicator stHistoryVal = getStatusHistoryValue();
            arithOrRlOperand = new ArithmeticOrRelationalOperand(stHistoryVal);
            break;

        case Constants.AR_VALUE_SET:
            List<Value> valList = getValueList();
            arithOrRlOperand = new ArithmeticOrRelationalOperand(valList);
            break;

        case Constants.AR_CURRENCY_FLD:
        case Constants.AR_CURRENCY_FLD_TRAN:
        case Constants.AR_CURRENCY_FLD_DB:
        case Constants.AR_CURRENCY_FLD_CURRENT:
            CurrencyPartInfo currencyPartInfo = getCurrencyPartInfo();
            arithOrRlOperand = new ArithmeticOrRelationalOperand(opType, currencyPartInfo);
            break;

        case Constants.AR_LOCAL_VARIABLE:
            int variable = getInt("Local Variable number (0 to 10) (0): ", 0);
            arithOrRlOperand = new ArithmeticOrRelationalOperand(variable);
            break;

        case Constants.AR_QUERY:
            QueryInfo qInfo = getQueryInfo();
            arithOrRlOperand = new ArithmeticOrRelationalOperand(qInfo);
            break;

        case Constants.AR_VALUE_SET_QUERY:
            ValueSetQuery queryValSet = getValueSetQuery(indent + "      ");
            arithOrRlOperand = new ArithmeticOrRelationalOperand(queryValSet);
            break;

        default:
            JavaDriver.outputWriter.driverPrintWarning(indent + "Invalid operation..");
            break;
        }

        return arithOrRlOperand;

    }

    public static ArithmeticOperationInfo getArithmeticOperationInfo(String indent) throws IOException, ARException {

    	return getArithmeticOperationInfo(null, indent);
    }
    
    public static ArithmeticOperationInfo getArithmeticOperationInfo(List<IQuerySource> fieldSources, 
    		String indent) throws IOException, ARException {

        if (getBoolean(indent + "Null ArithmeticOperationInfo (F): ", false)) {
            return null;
        }

        ArithmeticOrRelationalOperand leftOperand = null;
        ArithmeticOrRelationalOperand rightOperand = null;

        int operation = getInt(indent + "Arithmetic op code -- +, -, *, /, %, unary - (1 - 6): ", 1);

        if (operation != 6) // 6 for unary negation
        {
            JavaDriver.outputWriter.driverPrintPrompt(indent + "Left Operand - ");
            leftOperand = getArithmeticOrRelationalOperand(fieldSources, indent);
        }

        JavaDriver.outputWriter.driverPrintPrompt(indent + "Right Operand - ");

        rightOperand = getArithmeticOrRelationalOperand(fieldSources, indent);

        return new ArithmeticOperationInfo(operation, leftOperand, rightOperand);
    }

    public static RelationalOperationInfo getRelationalOperationInfo() throws IOException, ARException {
        return getRelationalOperationInfo("");
    }
    
    public static RelationalOperationInfo getRelationalOperationInfo(String indent) throws IOException, ARException {
        return getRelationalOperationInfo(null, indent);
    }
    
    public static RelationalOperationInfo getRelationalOperationInfo(List<IQuerySource> fieldSources, 
    		String indent) throws IOException, ARException {

        if (getBoolean(indent + "Null RelationalOperationInfo (F): ", false)) {
            return null;
        }
        int operation = getInt(indent + "Relational op code - EQ, GT, GE, LT, LE, NE, LIKE, IN, NOT IN  (1 - 9): ", 1);

        JavaDriver.outputWriter.driverPrintPrompt(indent + "Left operand - ");
        ArithmeticOrRelationalOperand leftOperand = getArithmeticOrRelationalOperand(fieldSources, indent);

        JavaDriver.outputWriter.driverPrintPrompt(indent + "Right operand - ");
        ArithmeticOrRelationalOperand rightOperand = getArithmeticOrRelationalOperand(fieldSources, indent);

        return new RelationalOperationInfo(operation, leftOperand, rightOperand);
    }

    public static QualifierInfo getQualifierInfo() throws IOException, ARException {
    	return getQualifierInfo(null, "Qualifier Info", "");
    }

    public static QualifierInfo getQualifierInfo(List<IQuerySource> fieldSources, String label, String indent) throws IOException, ARException {

        JavaDriver.outputWriter.driverPrintPrompt(indent + label + ": \n");

        if (getBoolean(indent + "Null " + label + " (F): ", false)) {
            return null;
        }

        int operation = getInt(indent + "None, And, Or, Not, Relop or FromField (0, 1, 2, 3, 4, 5) (0): ", 0);

        IARQualifierOperand opLeft = null;
        IARQualifierOperand opRight = null;

        QualifierInfo qInfo = null;

        switch (operation) {
        case QualifierInfo.AR_COND_OP_NONE:
            // nothing to load if no qualifier
            break;

        case QualifierInfo.AR_COND_OP_AND:
            opLeft = getQualifierInfo(fieldSources, label, indent);
            JavaDriver.outputWriter.driverPrintPrompt(indent + "AND\n");
            opRight = getQualifierInfo(fieldSources, label, indent);
            qInfo = new QualifierInfo(QualifierInfo.AR_COND_OP_AND, (QualifierInfo) opLeft, (QualifierInfo) opRight);
            break;

        case QualifierInfo.AR_COND_OP_OR:
            opLeft = getQualifierInfo(fieldSources, label, indent);
            JavaDriver.outputWriter.driverPrintPrompt(indent + "OR\n");
            opRight = getQualifierInfo(fieldSources, label, indent);
            qInfo = new QualifierInfo(QualifierInfo.AR_COND_OP_OR, (QualifierInfo) opLeft, (QualifierInfo) opRight);
            break;

        case QualifierInfo.AR_COND_OP_NOT:
            opLeft = getQualifierInfo(fieldSources, label, indent);
            qInfo = new QualifierInfo(QualifierInfo.AR_COND_OP_NOT, (QualifierInfo) opLeft, null);
            break;

        case QualifierInfo.AR_COND_OP_REL_OP:
            RelationalOperationInfo rOpInfo = getRelationalOperationInfo(fieldSources, indent);
            qInfo = new QualifierInfo(rOpInfo);
            break;

        case QualifierInfo.AR_COND_OP_FROM_FIELD:
            int fid = getInt("Field id (1):", 1);
            QualifierFromFieldInfo fromFidInfo = new QualifierFromFieldInfo(fid);
            qInfo = new QualifierInfo(fromFidInfo);
            break;

        default:
            break;
        }
        return qInfo;
    }
    
    public static QualifierInfo[] getQualifierInfoList() throws IOException, ARException {

        QualifierInfo[] qualifierInfoList = null;

        int numItems = getInt("  Number of  qualifierInfo objects(0): ", 0);
        if (numItems != 0) {
            qualifierInfoList = new QualifierInfo[numItems];
            for (int i = 0; i < numItems; i++) {
                qualifierInfoList[i] = getQualifierInfo();
            }
        }
        return qualifierInfoList;
    }

    public static SortInfo getSortInfo() throws IOException {
    	return getSortInfoWithSources(null);
    }

    public static List<SortInfo> getSortInfoList() throws IOException {
    	return getSortInfoListWithSources(null);
    }

    public static List<SortInfo> getSortInfoListWithSources(List<IQuerySource> sources) throws IOException {    	
        List<SortInfo> sortInfoList = null;
        int numItems = getInt("Number of sort fields (0): ", 0);
        if (numItems != 0) {
            sortInfoList = new ArrayList<SortInfo>(numItems);
            for (int i = 0; i < numItems; i++) {
                sortInfoList.add(getSortInfoWithSources(sources));
            }
        }

        return sortInfoList;
    }
    
    public static SortInfo getSortInfoWithSources(List<IQuerySource> sources) throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("   Sort list entry\n");

        if (getBoolean("Null SortInfo (F): ", false)) {
            return null;
        }

        int id = getInt("      Internal id of field to sort on (0): ", 0);
        int order = getInt("      Ascending or Descending (1 or 2) (1): ", 1);
        
        if(sources != null && sources.size() > 0) {
        	int idx = getInt("      Field source (" + getQuerySourcesPrompt(sources) + ") (0): ", 0);        	
        	return new SortInfo (id, sources.get(idx), order);
        }
        else
        	return new SortInfo(id, order);
    }
    
    public static IndexInfo getIndexInfo() throws IOException {
        JavaDriver.outputWriter.driverPrintPrompt("   Index list entry\n");

        if (getBoolean("Null IndexInfo (F): ", false)) {
            return null;
        }

        List<Integer> fieldIds = InputReader.getIntegerList();

        boolean unique = getBooleanForChangingInfo("      Unique index (F): ", false);

        String nameId = getString("Name", "");

        return new IndexInfo(fieldIds, unique, nameId);
    }

    public static List<IndexInfo> getIndexInfoList() throws IOException {

        List<IndexInfo> indexList = null;

        int numItems = getInt("Number of indexes (0): ", 0);

        if (numItems != 0) {
            indexList = new ArrayList<IndexInfo>(numItems);
            for (int i = 0; i < numItems; i++) {
                indexList.add(getIndexInfo());
            }
        }

        return indexList;
    }

    public static ArchiveInfo getArchiveInfo() throws IOException, ARException {
        int no_days_time, getDate;
        ArchiveInfo archive = new ArchiveInfo();
        int enable = getInt("Enable (0): ", 0);
        int type = getInt("Archive Type (0-None, 1-form, 2-delete, 3-form&delete): ", 0);
        String form = null;
        if ((type == 1) || (type == 3)) {
            form = getString("Archive Form Name ():", "");
        }
        QualifierInfo qualifierInfo = getQualifierInfo();
        archive.setEnable(enable != 0);
        archive.setArchiveType(type);
        archive.setQualifier(qualifierInfo);
        archive.setArchiveDest(form);
        BitSet bsDays = new BitSet(32);
        BitSet bsweekDays = new BitSet(7);
        BitSet bsHours = new BitSet(24);
        int minute = 0;        
        if (getBooleanForChangingInfo("Do you want to archive now <F>", false)) {
            int secsFromNow = getInt("Enter secs from now: (>= 0) (0): ", 0);
            Calendar now = Calendar.getInstance();
            now.add(Calendar.SECOND, secsFromNow);
            int dayOfMonth = now.get(Calendar.DAY_OF_MONTH);
            int dayOfWeek = now.get(Calendar.DAY_OF_WEEK);
            int hourOfDay = now.get(Calendar.HOUR_OF_DAY);
            bsDays.set(dayOfMonth - 1);
            bsweekDays.set(dayOfWeek - 1);
            if (hourOfDay > 0){
                hourOfDay = hourOfDay - 1;
            }
            bsHours.set(hourOfDay);
            minute = now.get(Calendar.MINUTE);
        } else {
            no_days_time = getInt("how many days to set in day/month format? (> 0) (1): ", 1);
            for (int i = 0; i < no_days_time; i++) {
                getDate = getInt("date of the day, 0 to 30 for month/day (0): ", 0);
                bsDays.set(getDate);
            }
            no_days_time = getInt("how many days to set in day/week format? (> 0) (1): ", 1);
            for (int i = 0; i < no_days_time; i++) {
                getDate = getInt("date of the day, 0 to 6 for sunday to saturday (0): ", 0);
                bsweekDays.set(getDate);
            }
            no_days_time = getInt("how many hour to set in a day? (> 0) (1): ", 1);
            for (int i = 0; i < no_days_time; i++) {
                getDate = getInt("hour of the day, 0 to 23 for 24 hours of a day (0): ", 0);
                bsHours.set(getDate);    
            }
            minute = getInt("set minute of the hour ? (0-59) (0): ", 0);
        }
        EscalationTime timeInfo = new EscalationTime(bsDays, bsweekDays, bsHours, minute);
        archive.setArchiveTmInfo(timeInfo);
        return archive;
    }

    public static AuditInfo getAuditInfo() throws IOException, ARException {
        AuditInfo auditInfo = new AuditInfo();
        int style = getInt("Audit Style (0-None, 1-Copy, 2-Log): ", 1);
        if (style == 0)
            return null;

        if ((style == 1) || (style == 2)) {
            auditInfo.setAuditStyle(style);
            String form = getString("Audit Form Name ():", "");
            auditInfo.setAuditForm(form);
        }

        boolean enable = getBoolean("Enable Audit (F): ", false);
        auditInfo.setEnable(enable);
        QualifierInfo qualifierInfo = getQualifierInfo();
        auditInfo.setQualifier(qualifierInfo);
        return auditInfo;
    }

    public static Form getForm() throws IOException, ARException {

        int type = getInt("Form Type (1): ", 1);

        switch (type) {
        case Constants.AR_SCHEMA_REGULAR:
            return new RegularForm();
        case Constants.AR_SCHEMA_DIALOG:
            return new DisplayOnlyForm();
        case Constants.AR_SCHEMA_JOIN:
            return getJoinForm();
        case Constants.AR_SCHEMA_VIEW:
            return getViewForm();
        case Constants.AR_SCHEMA_VENDOR:
            return getVendorForm();
        default:
            return new RegularForm();
        }
    }

    public static Container getContainer() throws IOException {
        int type = getInt("Container Type (1): ", 1);

        switch (type) {
        case Constants.ARCON_GUIDE:
            return new ActiveLinkGuide();
        case Constants.ARCON_PACK:
            return new PackingList();
        case Constants.ARCON_FILTER_GUIDE:
            return new FilterGuide();
        case Constants.ARCON_WEBSERVICE:
            return new WebService();
        case Constants.ARCON_APP:
        default:
            return new ApplicationContainer();
        }
    }

    public static Field getField() throws IOException {
        int type = getInt("Field Datatype (2): ", 2);

        switch (type) {
        case Constants.AR_DATA_TYPE_INTEGER:
            return new IntegerField();
        case Constants.AR_DATA_TYPE_REAL:
            return new RealField();
        case Constants.AR_DATA_TYPE_DIARY:
            return new DiaryField();
        case Constants.AR_DATA_TYPE_ENUM:
            return new SelectionField();
        case Constants.AR_DATA_TYPE_TIME:
            return new DateTimeField();
        case Constants.AR_DATA_TYPE_DECIMAL:
            return new DecimalField();
        case Constants.AR_DATA_TYPE_ATTACH:
            return new AttachmentField();
        case Constants.AR_DATA_TYPE_CURRENCY:
            return new CurrencyField();
        case Constants.AR_DATA_TYPE_DATE:
            return new DateOnlyField();
        case Constants.AR_DATA_TYPE_TIME_OF_DAY:
            return new TimeOnlyField();
        case Constants.AR_DATA_TYPE_TABLE:
            return new TableField();
        case Constants.AR_DATA_TYPE_COLUMN:
            return new ColumnField();
        case Constants.AR_DATA_TYPE_VIEW:
            return new ViewField();
        case Constants.AR_DATA_TYPE_DISPLAY:
            return new DisplayField();
        case Constants.AR_DATA_TYPE_CHAR:
        default:
            return new CharacterField();
        }
    }

    public static FieldMapping getFieldMappingInfo() throws IOException {

        int fieldType = getInt("Field Mapping Type (1): ", 1);
        switch (fieldType) {
        case Constants.AR_FIELD_NONE:
            return null;

        case Constants.AR_FIELD_REGULAR:
            return new RegularFieldMapping( );

        case Constants.AR_FIELD_JOIN:
            int index = getInt("   form index (0): ", 0);
            int field = getInt("   real Id (0): ", 0);

            return new JoinFieldMapping(index, field);

        case Constants.AR_FIELD_VIEW:
            return new ViewFieldMapping(getString("Field Name", ""));

        case Constants.AR_FIELD_VENDOR:
            return new VendorFieldMapping(getString("Field Name", ""));

        default:
            return null;
        }
    }

    public static PropInfo getPropInfo() throws IOException, ARException {

        if (getBoolean("Null PropInfo (F): ", false)) {
            return null;
        }

        int tag = getInt("Prop Tag - ( 0-500 ): ", 0);

        Value val = getValue();

        return new PropInfo(tag, val);
    }

    public static PropInfo[] getPropInfoList() throws IOException, ARException {

        PropInfo[] propList = null;

        int numItems = getInt("Number of Properties (0): ", 0);

        if (numItems != 0) {
            propList = new PropInfo[numItems];
            for (int i = 0; i < numItems; i++) {
                propList[i] = getPropInfo();
            }
        }

        return propList;
    }

    public static DisplayPropertyMap getDisplayPropertyMap() throws IOException, ARException {

        DisplayPropertyMap propList = null;

        int numItems = getInt("Number of Properties (0): ", 0);

        if (numItems != 0) {
            propList = new DisplayPropertyMap();
            for (int i = 0; i < numItems; i++) {
                PropInfo pi = getPropInfo();
                propList.put(pi.getPropertyTag(), pi.getPropertyValue());
            }
        }

        return propList;
    }

    public static ViewDisplayPropertyMap getViewDisplayPropertyMap() throws IOException, ARException {

        ViewDisplayPropertyMap propList = null;

        int numItems = getInt("Number of Properties (0): ", 0);

        if (numItems != 0) {
            propList = new ViewDisplayPropertyMap();
            for (int i = 0; i < numItems; i++) {
                PropInfo pi = getPropInfo();
                propList.put(pi.getPropertyTag(), pi.getPropertyValue());
            }
        }

        return propList;
    }

    public static ObjectPropertyMap getObjectPropertyMap() throws IOException, ARException {

        ObjectPropertyMap propList = null;

        int numItems = getInt("Number of Properties (0): ", 0);

        if (numItems != 0) {
            propList = new ObjectPropertyMap();
            for (int i = 0; i < numItems; i++) {
                PropInfo pi = getPropInfo();
                propList.put(pi.getPropertyTag(), pi.getPropertyValue());
            }
        }

        return propList;
    }

    public static DisplayInstanceMap getDisplayInstanceMap() throws IOException, ARException {

        DisplayInstanceMap dim = new DisplayInstanceMap();

        JavaDriver.outputWriter.driverPrintPrompt("getting the Common Properties for this field\n");

        int numItems = getInt("Number of display Instances (0): ", 0);

        for (int i = 0; i < numItems; i++) {
            int id = getInt(" VUI id ( 0 ): ", 0);
            DisplayPropertyMap propMap = getDisplayPropertyMap();
            dim.put(id, propMap);
        }

        return dim;
    }

    public static AssignFieldInfo getAssignFieldInfo() throws IOException, ARException {

        if (getBoolean("Null AssignFieldInfo (F): ", false)) {
            return null;
        }

        Object obj = null;

        int tag = getInt("Field, status history, currency field (1, 4, 6) (1): ", 1);

        if (tag == 1) {
            obj = new Integer(getInt("Field id (0): ", 0));
        } else if (tag == 4) {
            obj = getStatusHistoryValue();
        } else if (tag == 6) {
            obj = getCurrencyPartInfo();
        }

        QualifierInfo qualifierInfo = getQualifierInfo();

        return new AssignFieldInfo(null, null, qualifierInfo, tag, obj, 0, 0);
    }

    public static DDEAction getDDEInfo() throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("   Active Link DDE Info:\n");

        if (getBoolean("Null DDEInfo (F): ", false)) {
            return null;
        }

        String serviceName = getString("      Service name (): ", "");
        String topic = getString("      Topic (): ", "");
        int action = getInt("      Action (execute, poke, request) (1-3) (1): ", 1);
        String pathToProgram = getString("      Path To Program (): ", "");

        String command = null;

        if (action != 3) {
            command = getString("      Command (): ", "");
        } else {
            command = null;
        }

        String item = null;

        if (getBooleanForChangingInfo("      Set an item string? (F): ", false)) {
            item = getString("      Item text (): ", "");
        } else {
            item = null;
        }

        return new DDEAction(serviceName, topic, item, action, pathToProgram, command);
    }

    public static OleAutomationAction getAutomationInfo() throws IOException, ARException {

        JavaDriver.outputWriter.driverPrintPrompt("   Active Link Automation Info:\n");

        if (getBoolean("Null AutomationInfo (F): ", false)) {
            return null;
        }

        String serverName = getString("      Auto Server name (): ", "");
        boolean isVisible = getBooleanForChangingInfo("      Showing Automation Server? (T): ", true);

        String classId = getString("      Class  Id (): ", "");
        String action = getString("      Automation Action (): ", "");
        List<COMMethodInfo> comMethodList = getCOMMethodInfoList();

        return new OleAutomationAction(serverName, classId, action, isVisible, comMethodList);
    }

    public static COMValueInfo getCOMValueInfo() throws IOException, ARException {

        if (getBoolean("Null COMValueInfo (F): ", false)) {
            return null;
        }

        int transId = getInt("      Transient Id (1): ", 1);
        String valueId = getString("      Value IId (used for method only)(): ", "");
        int valueType = getInt("      COM [Method( null -0, fieldId - 1)/Parm( null -0, value - 2)] Type (0): ", 0);

        int fieldId = 0;
        Value val = null;

        switch (valueType) {
        case Constants.AR_COM_METHOD_FIELDID:
            fieldId = getInt("      FieldId (1): ", 1);
            break;

        case Constants.AR_COM_PARM_VALUE:
            val = getValue();
            break;

        default:
            break;
        }
        return new COMValueInfo(valueId, transId, valueType, fieldId, val);
    }

    public static COMMethodParmInfo getCOMMethodParmInfo() throws IOException, ARException {

        if (getBoolean("Null COMMethodParmInfo (F): ", false)) {
            return null;
        }

        String name = getString("      Parameter Name (): ", "");

        int parmType = getInt(
                "      COM Parameter Type (VT_EMPTY/VT_NULL/VT_I2/VT_I4/VT_R4/VT_R8/VT_CY/VT_DATE/VT_BSTR/VT_DISPATCH/VT_ERROR/VT_BOOL/VT_VIANT/VT_UNKNOWN/VT_WBSTR) (0-14) (VT_I1/VT_UI1/VT_UI2/VT_UI4/VT_I8/VT_UI8/VT_INT/VT_UINT/VT_VOID/VT_HRESULT/VT_PTR) (16-26) (VT_LPSTR/VT_LPWSTR) (30-31) (VT_BLOB_OBJECT -- 70) (0): ",
                0);

        COMValueInfo val = getCOMValueInfo();

        return new COMMethodParmInfo(name, parmType, val);
    }

    public static List<COMMethodParmInfo> getCOMMethodParmInfoList() throws IOException, ARException {

        List<COMMethodParmInfo> parmList = null;

        int numItems = getInt("      Number of Parameters (0): ", 0);
        if (numItems != 0) {
            parmList = new ArrayList<COMMethodParmInfo>(numItems);
            for (int i = 0; i < numItems; i++) {
                parmList.add(getCOMMethodParmInfo());
            }
        }

        return parmList;
    }

    public static COMMethodInfo getCOMMethodInfo() throws IOException, ARException {

        if (getBoolean("Null COMMethodInfo (F): ", false)) {
            return null;
        }
        String name = getString("      Method Name (): ", "");

        String methodId = getString("      Method Interface Id (): ", "");

        int methodType = getInt(
                "      COM Method Type (VT_EMPTY/VT_NULL/VT_I2/VT_I4/VT_R4/VT_R8/VT_CY/VT_DATE/VT_BSTR/VT_DISPATCH/VT_ERROR/VT_BOOL/VT_VIANT/VT_UNKNOWN/VT_WBSTR) (0-14) (VT_I1/VT_UI1/VT_UI2/VT_UI4/VT_I8/VT_UI8/VT_INT/VT_UINT/VT_VOID/VT_HRESULT/VT_PTR) (16-26) (VT_LPSTR/VT_LPWSTR) (30-31) (VT_BLOB_OBJECT -- 70) (0): ",
                0);

        COMValueInfo value = getCOMValueInfo();

        List<COMMethodParmInfo> paramList = getCOMMethodParmInfoList();

        return new COMMethodInfo(name, methodId, methodType, value, paramList);
    }

    public static List<COMMethodInfo> getCOMMethodInfoList() throws IOException, ARException {

        List<COMMethodInfo> methodList = null;

        int numItems = getInt("      Number of Methods (1): ", 1);

        if (numItems != 0) {
            methodList = new ArrayList<COMMethodInfo>(numItems);
            for (int i = 0; i < numItems; i++) {
                methodList.add(getCOMMethodInfo());
            }
        }

        return methodList;
    }

    public static OpenWindowAction getOpenWindowAction() throws IOException, ARException {

        JavaDriver.outputWriter.driverPrintPrompt("   Active Link Open Dialog Info:\n");

        if (getBoolean("Null OpenDlgInfo (F): ", false)) {
            return null;
        }

        OpenWindowAction openDlg = new OpenWindowAction();

        String serverName = getString("Server Name ():", "");
        openDlg.setServerName(serverName);

        String formName = getString("Form name (): ", "");
        openDlg.setFormName(formName);

        String vuiLabel = getString("Vui Label (): ", "");
        openDlg.setVuiLabel(vuiLabel);

        boolean closeBox = getBooleanForChangingInfo("Close Box? (T): ", true);
        openDlg.setCloseBox(closeBox);

        List<FieldAssignInfo> inputFields = getFieldAssignInfoList();
        openDlg.setInputValueFieldPairs(inputFields);

        List<FieldAssignInfo> outputFields = getFieldAssignInfoList();
        openDlg.setOutputValueFieldPairs(outputFields);

        int mode = getInt("Window Mode( 0-20)(0):", 0);
        openDlg.setWindowMode(mode);

        String targetLocation = getString("Target Location ():", "");
        openDlg.setTargetLocation(targetLocation);

        QualifierInfo query = getQualifierInfo();
        openDlg.setQuery(query);

        boolean noMatchContinue = getBooleanForChangingInfo("   No Match Continue?(F):", false);
        openDlg.setNoMatchContinue(noMatchContinue);

        boolean suppressEmptyLst = getBooleanForChangingInfo("Suppress Empty List ? (F):", false);
        openDlg.setSuppressEmptyLst(suppressEmptyLst);

        MessageAction msg = getMessageInfo();
        openDlg.setMsg(msg);

        int interval = getInt("Polling interval (0):", 0);
        openDlg.setPollinginterval(interval);

        openDlg.setReportInfo(new OpenWindowAction.ReportInfo());

        List<SortInfo> sortOrderList = getSortInfoList();
        openDlg.setSortOrderList(sortOrderList);

        return openDlg;
    }

    public static CloseWindowAction getCloseWindowInfo() throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("   Active Link Close Window Info :\n");

        if (getBoolean("Null CloseWindowInfo (F): ", false)) {
            return null;
        }

        boolean closeAll = getBooleanForChangingInfo("Close All? (t): ", true);

        return new CloseWindowAction(closeAll);
    }

    public static CallGuideAction getCallGuideInfo() throws IOException, ARException {

        JavaDriver.outputWriter.driverPrintPrompt("   Active Link Call Guide Info:\n");

        if (getBoolean("Null CallGuideInfo (F): ", false)) {
            return null;
        }

        String name = getString("      Server Name: ", "");

        String guideName = getString("      Guide Name: ", "");

        int guideMode = getInt("      Guide Mode: (0): ", 0);

        int guideTableId = getInt("      Guide Table Id (0): ", 0);

        List<FieldAssignInfo> inputFields = getFieldAssignInfoList();

        List<FieldAssignInfo> outputFields = getFieldAssignInfoList();

        String sampleServer = getString("      Sample Server Name: ", "");

        String sampleGuide = getString("      Sample Guide Name: ", "");

        return new CallGuideAction(name, guideName, guideMode, guideTableId, inputFields, outputFields, sampleServer,
                sampleGuide);
    }

    public static ExitGuideAction getExitGuideInfo() throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("   Active Link Exit Guide Info:\n");

        if (getBoolean("Null ExitGuideInfo (F): ", false)) {
            return null;
        }

        boolean closeAll = getBooleanForChangingInfo("      Close All? (T): ", true);

        return new ExitGuideAction(closeAll);
    }

    public static GotoGuideLabelAction getGotoGuideLabelInfo() throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("   Active Link Goto Guide Label Info:\n");

        if (getBoolean("Null GotoGuideLabelInfo (F): ", false)) {
            return null;
        }

        String label = getString("      Label (): ", "");

        return new GotoGuideLabelAction(label);
    }

    public static WaitAction getWaitInfo() throws IOException {

        JavaDriver.outputWriter.driverPrintHeader("   Active Link Wait Info:");

        if (getBoolean("Null WaitInfo (F): ", false)) {
            return null;
        }

        String title = getString("      Continue Button Title ( Continue ): ", "Continue");

        return new WaitAction(title);
    }

    public static AssignSQLInfo getAssignSQLInfo() throws IOException {

        if (getBoolean("Null AssignSQLInfo (F): ", false)) {
            return null;
        }

        String server = getString("Server name (): ", "");

        String command = getString("SQL command (): ", "");

        int valueIndex = getInt("Index of returned value to select (1): ", 1);

        int noMatchOption = getInt("No match action -- error, null (1, 2) (2): ", 2);

        int multiMatchOption = getInt("Multi match action -- error, null, first, picklist (1, 2, 3, 4) (4): ", 4);

        return new AssignSQLInfo(server, command, valueIndex, noMatchOption, multiMatchOption);
    }

    public static AssignFilterApiInfo getAssignFilterApiInfo() throws IOException, ARException {

        if (getBoolean("Null AssignFilterApiInfo (F): ", false)) {
            return null;
        }

        String name = getString("      Service Name: ", "");
        JavaDriver.outputWriter.driverPrintPrompt("      Input Value List:\n");

        List<AssignInfo> list = null;
        int numItems = getInt("      Number of Assignments (0): ", 0);

        if (numItems > 0) {
            list = new ArrayList<AssignInfo>(numItems);
            for (int i = 0; i < numItems; i++) {
                list.add(getAssignInfo());
            }
        }

        int index = getInt("      Index of the value field (1): ", 1);

        return new AssignFilterApiInfo(name, list, index);
    }

    public static AssignInfo getAssignInfo() throws IOException, ARException {

        if (getBoolean("Null AssignInfo (F): ", false)) {
            return null;
        }

        AssignInfo asnInfo = new AssignInfo();

        int type = getInt("Assign type:  None, Value, Field, Process, Arith, Function, DDE, SQL, Filter API(0 - 8): ",
                0);

        asnInfo.setAssignType(type);

        switch (type) {
        case AssignInfo.AR_ASSIGN_TYPE_VALUE:
            Value val = getValue();
            asnInfo.setValue(val);
            break;

        case AssignInfo.AR_ASSIGN_TYPE_FIELD:
            AssignFieldInfo fldInfo = getAssignFieldInfo();
            asnInfo.setField(fldInfo);
            break;

        case AssignInfo.AR_ASSIGN_TYPE_PROCESS:
            String process = getString("Process to run (): ", "");
            asnInfo.setProcess(process);
            break;

        case AssignInfo.AR_ASSIGN_TYPE_ARITH:
            ArithOpAssignInfo arAsnInfo = getArithOpAssignInfo();
            asnInfo.setArithOp(arAsnInfo);
            break;

        case AssignInfo.AR_ASSIGN_TYPE_FUNCTION:
            FunctionAssignInfo fnInfo = getFunctionAssignInfo();
            asnInfo.setFunction(fnInfo);
            break;

        case AssignInfo.AR_ASSIGN_TYPE_DDE:
            DDEAction ddeInfo = getDDEInfo();
            asnInfo.setDde(ddeInfo);
            break;

        case AssignInfo.AR_ASSIGN_TYPE_SQL:
            AssignSQLInfo sqlInfo = getAssignSQLInfo();
            asnInfo.setSql(sqlInfo);
            break;

        case AssignInfo.AR_ASSIGN_TYPE_FILTER_API:
            asnInfo.setFilterApi(getAssignFilterApiInfo());
            break;

        default:
            break;
        }

        return asnInfo;
    }

    public static ArithOpAssignInfo getArithOpAssignInfo() throws IOException, ARException {

        if (getBoolean("Null ArithOpAssignInfo (F): ", false)) {
            return null;
        }

        AssignInfo leftOperand = null;
        AssignInfo rightOperand = null;

        int operation = getInt("Arithmetic op code(+): +, -, *, /, %, unary - (1 - 6): ", 1);
        if (operation != 6) {
            JavaDriver.outputWriter.driverPrintPrompt("Left Operand - ");

            leftOperand = getAssignInfo();
        }

        JavaDriver.outputWriter.driverPrintPrompt("Right Operand - ");

        rightOperand = getAssignInfo();

        ArithOpAssignInfo asnInfo = new ArithOpAssignInfo();

        asnInfo.setOperation(operation);
        asnInfo.setOperandLeft(leftOperand);
        asnInfo.setOperandRight(rightOperand);

        return asnInfo;
    }

    public static FunctionAssignInfo getFunctionAssignInfo() throws IOException, ARException {

        if (getBoolean("Null FunctionAssignInfo (F): ", false)) {
            return null;
        }
        FunctionAssignInfo fnAssignInfo = new FunctionAssignInfo();

        int functionCode = getInt("Function code -- (1 - 50): ", 1);

        fnAssignInfo.setFunctionCode(functionCode);

        int numItems = getInt("Number of parameters (0): ", 0);

        if (numItems != 0) {
            List<AssignInfo> paramList = new ArrayList<AssignInfo>(numItems);
            for (int i = 0; i < numItems; i++) {
                JavaDriver.outputWriter.driverPrintPrompt("Parameter[" + i + "] - ");
                paramList.add(getAssignInfo());
            }

            fnAssignInfo.setParameterList(paramList);
        }

        return fnAssignInfo;
    }

    public static FieldAssignInfo getFieldAssignInfo() throws IOException, ARException {

        if (getBoolean("Null FieldAssignInfo (F): ", false)) {
            return null;
        }

        FieldAssignInfo fldAsnInfo = new FieldAssignInfo();

        int fieldId = getInt("Field id (0): ", 0);
        fldAsnInfo.setFieldId(fieldId);

        AssignInfo asnInfo = getAssignInfo();
        fldAsnInfo.setAssignment(asnInfo);

        return fldAsnInfo;
    }

    public static List<FieldAssignInfo> getFieldAssignInfoList() throws IOException, ARException {

        int numItems = getInt("   Number of field/assign pairs (0): ", 0);

        List<FieldAssignInfo> fldAssignInfoList = null;

        if (numItems != 0) {
            fldAssignInfoList = new ArrayList<FieldAssignInfo>(numItems);
            for (int i = 0; i < numItems; i++) {
                fldAssignInfoList.add(getFieldAssignInfo());
            }
        }

        return fldAssignInfoList;
    }

    public static SetFieldsAction getSetFieldsActionInfo(boolean isActiveLink) throws IOException, ARException {
/*        int type = getInt("Set Fields From (Current/Form/FilterAPI/SQL/WebService) (0-4): ", 1);

        SetFieldsAction action = null;
        switch (type) {
        case 0:
            action = new SetFieldsFromCurrentScreen();
            break;
        case 2:
            action = new SetFieldsFromFilterAPI();
            break;
        case 3:
            action = new SetFieldsFromSQL();
            break;
        case 4:
            action = new SetFieldsFromWebService();
            break;
        default:
        }
        return action;
*/
    	List<FieldAssignInfo> setFields = getFieldAssignInfoList();
    	String sampleServer =  new String( getString( "   Sample Server Name : ", "" ) );
        String sampleForm =  getString( "   Sample Form Name: ", "");

        SetFieldsAction action = null;
        for (FieldAssignInfo fldAssignInfo : setFields) {
        	AssignInfo assignInfo = fldAssignInfo.getAssignment();
            switch (assignInfo.getAssignType()) {
            case AssignInfo.AR_ASSIGN_TYPE_FILTER_API:
                action = new SetFieldsFromFilterAPI("", "", setFields);
                break;
            case AssignInfo.AR_ASSIGN_TYPE_SQL:
                action = new SetFieldsFromSQL("", "", setFields);
                break;
            default:
            	break;
            }
            if (action != null){
                action.setSampleServer(sampleServer);
                action.setSampleForm(sampleForm);   
            	break;
            }
        }
        return action;
    }

	public static PushFieldsAction getPushFieldsAction() throws IOException,
			ARException {
/*		int dataDestination = getInt(
				"Data Destination: Server, Sample Data (1-2) (1): ", 1);
		String sampleForm = null, sampleServer = null, runtimeFormValue = null;

		if (dataDestination == 2) {
			sampleServer = getString("   Sample Server Name : ", "");
			sampleForm = getString("   Sample Form Name: ", "");
			runtimeFormValue = getString("   RunTime Form Value: ", "");
		}
		Needs to be implement for sample data
*/		
		String pushToServer = getString("   Server Name for Push Fields : ",
				"@");
		String pushToForm = getString("   Form Name for the push fields : ", "");
		int noMatchOption = getInt(
				"No match action -- error, null, no action, submit (1-4) (2): ",
				2);
		int multiMatchOption = getInt(
				"Multi match action -- error, null, first, picklist, mod all, no action, submit (1-7) (4): ",
				4);
		List<PushFieldsInfo> fieldList = getPushFieldsInfoList();

		PushFieldsAction pfa = new PushFieldsAction();
		pfa.setPushFieldsList(fieldList);
		pfa.setNoMatchOption(noMatchOption);
		pfa.setMultiMatchOption(multiMatchOption);
		pfa.setPushToServer(pushToServer);
		pfa.setPushToForm(pushToForm);
		return pfa;
	}

    public static List<PushFieldsInfo> getPushFieldsInfoList() throws IOException, ARException {

        int numItems = getInt("   Number of field/assign pairs (0): ", 0);

        List<PushFieldsInfo> fieldList = null;

        if (numItems != 0) {
            fieldList = new ArrayList<PushFieldsInfo>(numItems);

            for (int i = 0; i < numItems; i++) {
                PushFieldsInfo cur = new PushFieldsInfo();

                cur.setField(getAssignFieldInfo());
                cur.setAssignment(getAssignInfo());

                fieldList.add(cur);

            }
        }

        return fieldList;
    }

    public static DirectSqlAction getSQLInfo() throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("Action Direct SQL:\n");

        if (getBoolean("Null SQLInfo (F): ", false)) {
            return null;
        }

        String server = getString("      Server (): ", "");

        String command = getString("      SQL command (): ", "");

        return new DirectSqlAction(server, command);
    }

    public static GotoAction getGotoActionInfo() throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("   Goto Action Info:\n");

        if (getBoolean("Null GotoActionInfo (F): ", false)) {
            return null;
        }

        int fieldIdOrValue = 0;

        int tag = getInt("      Field, Value, Forward, Backup (1-4): ", 1);

        switch (tag) {
        case 1:
            fieldIdOrValue = getInt("      FieldId (0): ", 0);
            break;

        case 2:
            fieldIdOrValue = getInt("      Execution Order (0): ", 0);
            break;

        case 3:
            fieldIdOrValue = getInt("    Execution Order Advance By(1): ", 1);
            break;

        case 4:
            fieldIdOrValue = getInt("      Execution Order Backup By (0): ", 1);
            break;

        default:
            break;
        }

        return new GotoAction(tag, fieldIdOrValue);

    }

    public static FilterAction getFilterActionInfo() throws IOException, ARException {

        JavaDriver.outputWriter.driverPrintHeader("Filter Action Info:");

        if (getBoolean("Null FilterActionInfo (F): ", false)) {
            return null;
        }

        FilterAction filterAction = null;

        int action = getInt(
                "   Notify, Message, Log, Fields, Process, Push, SQL, Goto Action, Call Guide, Exit Guide, Goto Guide Label(1-11): ",
                0);

        switch (action) {
        case Constants.AR_FILTER_ACTION_NOTIFY:
            NotifyAction notify = getNotifyActionInfo();
            filterAction = notify;
            break;

        case Constants.AR_FILTER_ACTION_MESSAGE:
            FilterMessageAction message = getFilterStatusInfo();
            filterAction = message;
            break;

        case Constants.AR_FILTER_ACTION_LOG:
            String file = getString("  Log File name(): ", "");
            filterAction = new LogAction(file);
            break;

        case Constants.AR_FILTER_ACTION_FIELDS:
            SetFieldsAction fields = getSetFieldsActionInfo(false);
            filterAction = fields;
            break;

        case Constants.AR_FILTER_ACTION_PROCESS:
            String process = getString("    Process ():", "");
            filterAction = new RunProcessAction(process);
            break;

        case Constants.AR_FILTER_ACTION_FIELDP:
            PushFieldsAction push = getPushFieldsAction();
            filterAction = push;
            break;

        case Constants.AR_FILTER_ACTION_SQL:
            DirectSqlAction sqlCommand = getSQLInfo();
            filterAction = sqlCommand;
            break;

        case Constants.AR_FILTER_ACTION_GOTOACTION:
            GotoAction gotoAction = getGotoActionInfo();
            filterAction = gotoAction;
            break;

        case Constants.AR_FILTER_ACTION_CALLGUIDE:
            filterAction = getCallGuideInfo();
            break;

        case Constants.AR_FILTER_ACTION_EXITGUIDE:
            filterAction = getExitGuideInfo();
            break;

        case Constants.AR_FILTER_ACTION_GOTOGUIDELABEL:
            filterAction = getGotoGuideLabelInfo();
            break;

        default:
            break;
        }
        return filterAction;
    }

    public static List<FilterAction> getFilterActionInfoList(boolean actionFlag) throws IOException, ARException {

        int numItems = 0;

        if (actionFlag) {
            numItems = getInt("Number of actions for the filter (1): ", 1);
        } else {
            numItems = getInt("Number of elses for the filter (0): ", 0);
        }

        List<FilterAction> list = null;

        if (numItems != 0) {
            list = new ArrayList<FilterAction>(numItems);
            for (int i = 0; i < numItems; i++) {
                list.add(getFilterActionInfo());
            }
        }

        return list;
    }

    public static RunMacroAction getActiveLinkMacroInfo() throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("   Active Link Macro Info:\n");

        if (getBoolean("Null ActiveLinkMacroInfo (F): ", false)) {
            return null;
        }

        String macroName = getString("      Macro name (): ", "");
        String text = getString("      Macro text(): ", "");

        Map<String, String> list = null;

        int numItems = getInt("      Number of macro parms (0): ", 0);

        if (numItems != 0) {
            list = new TreeMap<String, String>();

            String name = null;
            String val = null;
            for (int i = 0; i < numItems; i++) {
                name = getString("         Parm Name (): ", "");
                val = getString("         Parm Value (): ", "");

                list.put(name, val);
            }
        }

        return new RunMacroAction(macroName, text, list);
    }

    public static ChangeFieldAction getFieldCharacteristicsInfo() throws IOException, ARException {

        JavaDriver.outputWriter.driverPrintPrompt("   Active Link Field Characteristics:\n");

        int option = getInt("      Option (bitmask - 1 field reference) (0): ", 0);

        if (getBoolean("Null ChangeFieldAction (F): ", false)) {
            return null;
        }

        int fieldId = getInt("      Field Id (0): ", 0);

        String menu = null;
        if (getBooleanForChangingInfo("      Change menu? (F): ", false)) {
            menu = getString("      Char menu (): ", "");
        }

        DisplayPropertyMap propList = null;
        if (getBooleanForChangingInfo("      Change display Properties? (F): ", false)) {
            propList = getDisplayPropertyMap();
        }

        int focus = 0; // unchanged
        if (getBooleanForChangingInfo("      Change focus to this field? (F): ", false)) {
            focus = 1;
        }

        int accessOption = getInt("      Access option (unchanged, read-only, read/write, disable) (0-3) (0): ", 0);

        return new ChangeFieldAction(option, fieldId, menu, propList, focus, accessOption);
    }

    public static ActiveLinkAction getActiveLinkActionInfo() throws IOException, ARException {

        JavaDriver.outputWriter.driverPrintPrompt("Active Link Action Info:\n");

        if (getBoolean("Null ActiveLinkActionInfo (F): ", false)) {
            return null;
        }

        ActiveLinkAction action = null;

        int type = getInt(
                " Macro, Fields, Process, Message, Field Characteristics, DDE, Push, SQL, Automation, Open Dialog, Commit Changes, Close Window, Call Guide, Exit Guide, Goto Guide, Wait, Goto Action(1-17): ",
                1);

        switch (type) {
        case 1:
            RunMacroAction activeLinkMacro = getActiveLinkMacroInfo();
            action = activeLinkMacro;
            break;

        case 2:
            SetFieldsAction fieldList = getSetFieldsActionInfo(true);
            action = fieldList;
            break;

        case 3:
            String process = getString("   Command string (): ", "");
            action = new RunProcessAction(process);
            break;

        case 4:
            MessageAction message = getMessageInfo();
            action = message;
            break;

        case 5:
            ChangeFieldAction field = getFieldCharacteristicsInfo();
            action = field;
            break;

        case 6:
            DDEAction dde = getDDEInfo();
            action = dde;
            break;

        case 7:
            PushFieldsAction push = getPushFieldsAction();
            action = push;
            break;

        case 8:
            DirectSqlAction sql = getSQLInfo();
            action = sql;
            break;

        case 9:
            OleAutomationAction auto = getAutomationInfo();
            action = auto;
            break;

        case 10:
            OpenWindowAction openDlg = getOpenWindowAction();
            action = openDlg;
            break;

        case 11:
            CommitChangesAction commit = getCommitChangesInfo();
            action = commit;
            break;

        case 12:
            CloseWindowAction closeWnd = getCloseWindowInfo();
            action = closeWnd;
            break;

        case 13:
            CallGuideAction callGuide = getCallGuideInfo();
            action = callGuide;
            break;

        case 14:
            ExitGuideAction exitGuide = getExitGuideInfo();
            action = exitGuide;
            break;

        case 15:
            GotoGuideLabelAction guideLabel = getGotoGuideLabelInfo();
            action = guideLabel;
            break;

        case 16:
            WaitAction wait = getWaitInfo();
            action = wait;
            break;

        case 17:
            GotoAction gotoAction = getGotoActionInfo();
            action = gotoAction;
            break;

        default:
            break;
        }

        return action;
    }

    public static List<ActiveLinkAction> getActiveLinkActionInfoList(boolean actionFlag) throws IOException, ARException {

        int numItems = 0;

        if (actionFlag) {
            numItems = getInt("Number of actions for the active link (1): ", 1);
        } else {
            numItems = getInt("Number of elses for the active link (0): ", 0);
        }

        List<ActiveLinkAction> list = null;

        if (numItems != 0) {
            list = new ArrayList<ActiveLinkAction>(numItems);
            for (int i = 0; i < numItems; i++) {
                list.add(i, getActiveLinkActionInfo());
            }
        }

        return list;
    }

    public static PermissionInfo getPermissionInfo(boolean fieldFlag) throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("   Permission Info:\n");

        if (getBoolean("Null PermissionInfo (F): ", false)) {
            return null;
        }

        int groupId = getInt("      Group id (3): ", 0);

        int permissions = 0;

        if (fieldFlag) {
            permissions = getInt("      None, View, or Change (0, 1, 2): ", 0);
        } else {
            permissions = getInt("      None, Visible, or Hidden(0, 1, 2): ", 0);
        }

        return new PermissionInfo(groupId, permissions);
    }

    public static List<PermissionInfo> getPermissionInfoList(boolean fieldFlag) throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("Permission List:\n");

        int numItems = getInt("   Number of permission defns (0): ", 0);

        List<PermissionInfo> list = null;

        if (numItems != 0) {
            list = new ArrayList<PermissionInfo>(numItems);

            for (int i = 0; i < numItems; i++) {
                list.add(getPermissionInfo(fieldFlag));
            }
        }
        return list;
    }

    public static IntegerFieldLimit getIntegerLimitInfo() throws IOException {

        if (getBoolean("Null Form List Criteria (F): ", false)) {
            return null;
        }

        int low = getInt("   Integer range low (0): ", 0);
        int high = getInt("   Integer range high (5000): ", 5000);

        return new IntegerFieldLimit(low, high);
    }

    public static RealFieldLimit getRealLimitInfo() throws IOException {

        if (getBoolean("Null RealLimitInfo (F): ", false)) {
            return null;
        }
        double rangeLow = getDouble("   Real range low (0): ", (double) 0);
        double rangeHigh = getDouble("   Real range high (5000): ", (double) 5000);
        int precision = getInt("   Precision (-1 is no precision) (-1): ", -1);

        return new RealFieldLimit(rangeLow, rangeHigh, precision);
    }

    public static CharacterFieldLimit getCharLimitInfo() throws IOException {
        if (getBoolean("Null CharLimitInfo (F): ", false)) {
            return null;
        }
        int lengthUnits = getInt("   Length Units - Byte or Character (0 or 1) (0): ", 0);
        int storageOptionForCLOB = getInt("   Storage Option for CLOB - Default, In-Row or Out-of-Row (0, 1 or 2) (0): ", 0);
        int maxLength = getInt("   Maximum length (128): ", 128);
        int menuStyle = getInt("   Menu style - Append or Overwrite (1 or 2) (1): ", 1);
        int qbe = getInt("   Match operation - Anywhere, Leading match, or Equal (1 - 3) (1): ", 1);

        String charMenu = getString("	Character menu(): ", "");

        String pattern = getString("   Pattern (): ", "");

        int option = getInt("   FullText Options(0): ", 0);

        return new CharacterFieldLimit(maxLength, menuStyle, qbe, charMenu, pattern, option,
                lengthUnits, storageOptionForCLOB);
    }

    public static DiaryFieldLimit getDiaryLimitInfo() throws IOException {

        if (getBoolean("Null DiaryLimitInfo (F): ", false)) {
            return null;
        }
        int fullTextOptions = getInt("   FullText Options(0): ", 0);

        return new DiaryFieldLimit(fullTextOptions);
    }

    public static EnumItem getEnumItem() throws IOException {
        if (getBoolean("Null EnumItem (F): ", false)) {
            return null;
        }

        String name = getString("   Item Name " + ": ", "");
        int number = getInt("   Item Number (0): ", 0);
        return (new EnumItem(name, number));
    }

    public static List<EnumItem> getEnumItemList() throws IOException {
        List<EnumItem> enumItems = null;

        int numItems = getInt("   Number of enum items (0): ", 0);
        if (numItems != 0) {
            enumItems = new ArrayList<EnumItem>(numItems);

            for (int i = 0; i < numItems; i++) {
                enumItems.add(getEnumItem());
            }
        }

        return enumItems;
    }

    public static SelectionFieldLimit getEnumLimitInfo() throws IOException {
        if (getBoolean("Null EnumLimitInfo (F): ", false)) {
            return null;
        }
        int listStyle = getInt("Enum List Style (1): ", 1);
        switch (listStyle) {
        case 1:
            return (new SelectionFieldLimit(getStringArray("", "Selection Field Enum Item")));
        case 2:
            return (new SelectionFieldLimit(getEnumItemList()));
        default:
            return null;
        }
    }

    public static AttachmentFieldLimit getAttachmentLimitInfo() throws IOException {

        if (getBoolean("Null AttachmentLimitInfo (F): ", false)) {
            return null;
        }

        int maxSize = getInt("   maxSize(0): ", 0);

        int type = Constants.AR_ATTACH_FIELD_TYPE_EMBED;

        int fullTextOptions = getInt("   FullText Options(0): ", 0);

        return new AttachmentFieldLimit(maxSize, type, fullTextOptions);
    }

    public static TableFieldLimit getTableLimitInfo() throws IOException, ARException {

        if (getBoolean("Null TableLimitInfo (F): ", false)) {
            return null;
        }
        String form = getString("   form name: ", "");

        String server = getString("   server name: ", "");

        QualifierInfo qualifier = getQualifierInfo();

        int maxRetrieve = getInt("  Max rows to retrieve (10): ", 10);
        int numColumns = 0;

        String sampleForm = getString("   sample form name: ", "");

        String sampleServer = getString("   sample server name: ", "");

        return new TableFieldLimit(numColumns, qualifier, maxRetrieve, form, server, sampleForm, sampleServer);
    }

    public static ColumnFieldLimit getColumnLimitInfo() throws IOException {

        if (getBoolean("Null ColumnLimitInfo (F): ", false)) {
            return null;
        }
        int parentID = getInt("   Parent Table field Id (0): ", 0);

        int dataFieldID = getInt("   Data field Id (0): ", 0);
        int dataSource = getInt("   Data Source(0): ", 0);
        int colLength = getInt("   Length to display(10) : ", 10);

        return new ColumnFieldLimit(parentID, dataFieldID, dataSource, colLength);
    }

    public static DecimalFieldLimit getDecimalLimitInfo() throws IOException {

        if (getBoolean("Null DecimalLimitInfo (F): ", false)) {
            return null;
        }

        String low = getString("   Decimal range low (0.0): ", "0.0");
        String high = getString("   Decimal range high (5000.0): ", "5000.0");
        int precision = getInt("   Precision (0): ", 0);

        return new DecimalFieldLimit(low, high, precision);
    }

    public static List<CurrencyDetail> getCurrencyDetail(String prompt, int defaultOccurances) throws IOException {
        List<CurrencyDetail> currencyDetail = null;
        int i;
        int numCurrencies = getInt(prompt + "(" + defaultOccurances + "):", defaultOccurances);

        if (numCurrencies > 0) {
            currencyDetail = new ArrayList<CurrencyDetail>(numCurrencies);
        }

        for (i = 0; i < numCurrencies; i++) {
            String currencyCode = getString("   Currency Code (USD): ", "USD");
            int precision = getInt("   Precision (0): ", 0);
            currencyDetail.add(new CurrencyDetail(currencyCode, precision));
        }

        return currencyDetail;
    }

    public static CurrencyFieldLimit getCurrencyLimitInfo() throws IOException {

        String low = getString("   Currency range low (0.0): ", "0.0");
        String high = getString("   Currency range high (5000.0): ", "5000.0");
        int precision = getInt("   Precision (0): ", 0);
        List<CurrencyDetail> functional = getCurrencyDetail("    Number of functional Currencies", 1);
        List<CurrencyDetail> allowable = getCurrencyDetail("   Number of Allowable Currencies", 1);

        return new CurrencyFieldLimit(low, high, precision, functional, allowable);
    }

    public static ViewFieldLimit getViewLimits() throws IOException {
        if (getBoolean("Null ViewLimits (F): ", false)) {
            return null;
        }

        int maxLength = getInt("   Maximum length (128): ", 128);

        return new ViewFieldLimit(maxLength);
    }

    public static DisplayFieldLimit getDisplayLimits() throws IOException {
        if (getBoolean("Null DisplayLimits (F): ", false)) {
            return null;
        }
        int lengthUnits = getInt("   Length Units - Byte or Character (0 or 1) (0): ", 0);
        int maxLength = getInt("   Maximum length (128): ", 128);

        return new DisplayFieldLimit(maxLength, lengthUnits);
    }

    public static MenuItem getCharMenuItemInfo() throws IOException {
        JavaDriver.outputWriter.driverPrintPrompt("Char Menu Item Info:\n");

        if (getBoolean("Null CharMenuItemInfo (F): ", false)) {
            return null;
        }

        String menuLabel = getString("    Menu Label: ", "");
        int menuType = getInt("    Menu type - Value Or Menu (1, 2) (1):", 1);

        MenuItem charMenuItem = null;
        switch (menuType) {
        case 1:
            String menuItem = getString("    Char menu text(): ", "");
            charMenuItem = new MenuItem(menuLabel, menuItem);
            break;

        case 2:
            List<MenuItem> menuInfo = getCharMenuItemInfoList();
            charMenuItem = new MenuItem(menuLabel, menuInfo);
            break;

        default:
            break;
        }

        return charMenuItem;
    }

    public static ListMenu getCharMenuListInfo() throws IOException {

        if (getBoolean("Null CharMenuListInfo (F): ", false)) {
            return null;
        }

        int numItems = getInt("   Number of char menu items (0): ", 0);
        List<MenuItem> list = null;
        if (numItems != 0) {
            list = new ArrayList<MenuItem>(numItems);
            for (int i = 0; i < numItems; i++) {
                list.add(getCharMenuItemInfo());
            }
        }

        return new ListMenu(list);
    }

    public static QueryMenu getCharMenuQueryInfo() throws IOException, ARException {

        JavaDriver.outputWriter.driverPrintPrompt("    Char Menu Query Info:\n");

        if (getBoolean("Null CharMenuQueryInfo (F): ", false)) {
            return null;
        }

        String form = getString("    Form Name (): ", "");

        String server = getString("      Server (): ", "");

        QualifierInfo qualifier = getQualifierInfo();

        int labelField = getInt("      Id of the label field (0): ", 0);

        int valueField = getInt("      Id of the value field (0): ", 0);

        boolean sortOnLabel = getBooleanForChangingInfo("      Sort the label field (T): ", true);

        String sampleForm = getString("    Sample Form Name (): ", "");

        String sampleServer = getString("      Sample Server (): ", "");

        return new QueryMenu(form, server, qualifier, labelField, valueField, sortOnLabel, sampleForm, sampleServer);
    }

    public static FileMenu getCharMenuFileInfo() throws IOException {

        JavaDriver.outputWriter.driverPrintHeader("Char Menu FILE INFO:");

        if (getBoolean("Null CharMenuFileInfo (F): ", false)) {
            return null;
        }

        int type = getInt("       File location  Server or Client (1 or 2) (1): ", 1);
        String name = getString("      File Name():", "");

        return new FileMenu(type, name);
    }

    public static SqlMenu getCharMenuSQLInfo() throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("Char Menu SQL INFO:\n");

        if (getBoolean("Null CharMenuSQLInfo (F): ", false)) {
            return null;
        }
        String server = getString("      Server (): ", "");

        String command = getString("      SQL command (): ", "");

        int labelIndex = getInt("      Index of the label field (1): ", 1);

        int valueIndex = getInt("      Index of the value field (1): ", 1);

        return new SqlMenu(server, command, labelIndex, valueIndex);
    }

    public static List<MenuItem> getCharMenuItemInfoList() throws IOException {
        int numItems = getInt("   Number of char menu items (0): ", 0);

        List<MenuItem> list = null;
        if (numItems > 0) {
            list = new ArrayList<MenuItem>(numItems);
            for (int i = 0; i < numItems; i++) {
                list.add(getCharMenuItemInfo());
            }
        }

        return list;
    }

    public static DataDictionaryMenu getCharMenuDDInfo() throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("   Char Menu Data-Dictionary info:\n");

        if (getBoolean("Null CharMenuDDInfo (F): ", false)) {
            return null;
        }

        String server = getString("      Server name (): ", "");
        int nameType = getInt("      Name type (0 - 2) (0): ", 0);
        int valueFormat = getInt("      Value format (1 - 11) (2): ", 2);

        int structType = getInt("      Struct type ( 1(form) - 2(field) ) (1): ", 1);

        DataDictionaryMenu menu = null;

        switch (structType) {
        case 1:
            JavaDriver.outputWriter.driverPrintPrompt("      Data-Dictionary Form Info :\n");
            int formType = getInt(
                    "        Type of form (all,regular,join,view,uplink,downlink,dialog,vendor) (0-6,8) (0): ", 0);
            boolean includeHidden = getBooleanForChangingInfo("        Include hidden forms (T): ", true);

            menu = (DataDictionaryMenu) new FormDataDictionaryMenu(server, nameType, valueFormat, formType,
                    includeHidden);
            break;

        case 2:
            JavaDriver.outputWriter.driverPrintPrompt("        Data-Dictionary Field Info :\n");
            int fieldType = getInt("        Field Type - data, trim, control, page, pholder, table,\n "
                    + " column, attach, attachpool  (1, 2, 4, 8, 16, 32, 64, 128, 256) (129): ", 129);
            String name = getString("        Form name (): ", "");

            menu = (DataDictionaryMenu) new FieldDataDictionaryMenu(server, nameType, valueFormat, fieldType, name);
            break;

        default:
            break;
        }
        return menu;

    }

    public static Menu getCharMenuSSInfo() throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("    Char Menu Server-Side info:\n");

        if (getBoolean("Null CharMenuSSInfo (F): ", false)) {
            return null;
        }
        String menuName = getString("      Menu name (): ", "");
        Menu menu = new SqlMenu(null, null, 0, 0);
        menu.setName(menuName);
        return menu;
    }

    public static Menu getMenu() throws IOException, ARException {

        JavaDriver.outputWriter.driverPrintPrompt("Char Menu Info:\n");

        int menuType = getInt("    Menu type - None, List, Query, File, SQL, SS, DD (0 - 6) ( 1 ):", 1);

        Menu menu = null;

        switch (menuType) {
        case Constants.AR_CHAR_MENU_LIST:
            menu = (Menu) getCharMenuListInfo();
            break;
        case Constants.AR_CHAR_MENU_QUERY:
            menu = (Menu) getCharMenuQueryInfo();
            break;
        case Constants.AR_CHAR_MENU_FILE:
            menu = (Menu) getCharMenuFileInfo();
            break;
        case Constants.AR_CHAR_MENU_SQL:
            menu = (Menu) getCharMenuSQLInfo();
            break;
        case Constants.AR_CHAR_MENU_DATA_DICTIONARY:
            menu = (Menu) getCharMenuDDInfo();
        case Constants.AR_CHAR_MENU_SS:
            menu = (Menu) getCharMenuSSInfo();
        default:
            break;
        }

        return menu;
    }

    public static StructItemInfo getStructItemInfo() throws IOException {

        if (getBoolean("Null StructItemInfo (F): ", false)) {
            return null;
        }

        int options = 0;
        setNullPromptOption(true);
        
        int type = getInt("   Form(full,defn,view,mail),Filter,ActLink,<7-obsolete>,CharMenu,\n "
                + "   Escalation,Dist Map, Form(min view), Container, DistPool, VUI,\n"
                + "   Field, Application, Image, VUI(locale based)(1-8, 9-15, 16-18): ", 0);

        String name = getString("Structure name ", "");
        String selectedElements[] = null;

        if (type == StructItemInfo.VUI || type == StructItemInfo.SCHEMA_MAIL) {
            JavaDriver.outputWriter.driverPrintPrompt("   VUIs to select (supply VUI's DB name):\n");
            selectedElements = getStringArray("", "VUI DB Name");
        } else if (type == StructItemInfo.FIELD) {
            selectedElements = getStringArray("", "Field Name");
        }
        else if (type == StructItemInfo.APPLICATION) {
        	if (getBoolean("Integration Workflow Only (F): ", false)) {
                options |= Constants.AR_EXPORT_APP_INTEGRATION_WORKFLOW;
              	JavaDriver.outputWriter.driverPrintPrompt("   Applicaiotns to select:\n");
            	selectedElements = getStringArray("", "Applications");                
            }
        	else
        	{
        		if (getBoolean("Include Shared Workflow (F): ", false)) {
                    options |= Constants.AR_EXPORT_SHARED_WORKFLOW;
                }	
        		
        	    if (getBoolean("Include only Locale VUI and data T/F? (F): ", false)) {
                    options |= Constants.AR_EXPORT_LOCALE_ONLY + Constants.AR_EXPORT_SELECTED_LOCALES;
                  	JavaDriver.outputWriter.driverPrintPrompt("   Locales to select:\n");
                	selectedElements = getStringArray("", "Locale");                    
                }
        	    else
        	    {
        	            	    
        	    	int localType = getInt("Locales to include: (0-All 1-Default only 2-Selected) (0):", 0);  
        	    
        	    	if (localType == 1){
        	    		options |= Constants.AR_EXPORT_DEFAULT_LOCALE;
        	    	}
        	    	else if (localType == 2){
        	    		options |= Constants.AR_EXPORT_SELECTED_LOCALES;
        	    		JavaDriver.outputWriter.driverPrintPrompt("   Locales to select:\n");
        	    		selectedElements = getStringArray("", "Locale");
        	    	}
        	    }        	    	        	            	        	
        	}        	                	
        } 
        setNullPromptOption(false);
        return new StructItemInfo(type, name, selectedElements, options);
    }   

    public static List<StructItemInfo> getStructItemInfoList() throws IOException {

        int expFormat = getInt("   Format: AR_DEF, XML (1,2) (1): ", 1);
        JavaDriver.outputWriter.driverPrintPrompt("Struct ItemInfo List:\n");

        int numItems = getInt("   Number of structure items (0): ", 0);

        List<StructItemInfo> list = new ArrayList<StructItemInfo>();

        if (numItems != 0) {
            for (int i = 0; i < numItems; i++) {
                list.add(getStructItemInfo());
            }
        }

        if (expFormat == 2) {
            for (StructItemInfo si : list) {
                si.setType(si.getType() | Constants.AR_STRUCT_XML_OFFSET);
            }
        }
        return list;
    }

    public static ServerInfo getServerInfo() throws IOException, ARException {
        if (getBoolean("Null ServerInfo (F): ", false)) {
            return null;
        }
        int operation = getInt("    Operation (1-"+Constants.AR_MAX_SERVER_INFO_USED+") (1):", 1);
        Value val = getValue();

        return new ServerInfo(operation, val);
    }

    public static ServerInfoMap getServerInfoMap() throws IOException, ARException {
        int numItems = getInt("   Number of server info operations (0): ", 0);

        ServerInfoMap list = new ServerInfoMap();

        if (numItems != 0) {
            for (int i = 0; i < numItems; i++) {
                int operation = getInt("    Operation (1-"+Constants.AR_MAX_SERVER_INFO_USED+") (1):", 1);
                Value value = getValue();
                list.put(operation, value);
            }
        }

        return list;
    }

    public static List<Reference> getReferenceList() throws IOException, ARException {
        int numItems = getInt("   Number of References (0): ", 0);

        List<Reference> list = null;

        if (numItems != 0) {
            list = new ArrayList<Reference>(numItems);

            for (int i = 0; i < numItems; i++) {
                list.add(getReference());
            }
        }

        return list;
    }

    public static Reference getReference() throws IOException, ARException {

        if (getBoolean("Null Reference (F): ", false)) {
            return null;
        }

        String label = getString("Reference Label ():", "");

        String desc = getString("Reference Description ():", "");

        ReferenceType type = getReferenceType();

        int dataType = getInt("References Data Type AR, EXTERNAL (0, 1) (0):", 0);

        if (dataType == 0) // System reference
        {
            String name = getString("ARS reference name", "");

            return new Reference(label, desc, type, name);
        } else // External reference
        {
            JavaDriver.outputWriter.driverPrintPrompt("   External reference access group ids: \n");
            List<Integer> idList = getIntegerList();
            JavaDriver.outputWriter.driverPrintPrompt("External Reference Value :\n");
            Value val = getValue();

            return new ExternalReference(label, desc, type, idList, val);
        }
    }

    public static ReferenceType getReferenceType() throws IOException {

        if (getBoolean("Null ReferenceType (F): ", false)) {
            return null;
        }

        JavaDriver.outputWriter.driverPrintPrompt("   Reference type none, form, filter, esc,actlink,\n");
        int type = getInt("      container,charmenu (0,2-7) (0): ", 0);

        return ReferenceType.toReferenceType(type);
    }

    public static List<ContainerOwner> getContainerOwnerList() throws IOException {

        if (getBoolean("Null ContainerOwnerList (F): ", false)) {
            return null;
        }

        int numItems = getInt("Number of container owner objects (0): ", 0);

        List<ContainerOwner> list = null;
        if (numItems != 0) {
            list = new ArrayList<ContainerOwner>(numItems);
            for (int i = 0; i < numItems; i++) {
                list.add(getContainerOwner());
            }
        }
        return list;
    }

    public static ContainerOwner getContainerOwner() throws IOException {

        if (getBoolean("Null ContainerOwnerInfo (F): ", false)) {
            return null;
        }

        int type = getInt("Container owner type (unowned, all, owned) (0-2) (0): ", 0);

        if (type == 0 || type == 1) {
            return new ContainerOwner(type);
        } else {
            String ownerName = getString("Container Owner Name", "");
            return new ContainerOwner(type, ownerName);
        }
    }

    public static ContainerType getContainerType() throws IOException {

        if (getBoolean("Null ContainerType (F): ", false)) {
            return null;
        }

        int type = getInt("Active Link Guide, Application, Packing List, Filter Guide, Web Service(1-5) (2): ", 2);

        switch (type) {
        case 1:
            return ContainerType.GUIDE;
        case 2:
            return ContainerType.APPLICATION;
        case 3:
            return ContainerType.PACKINGLIST;
        case 4:
            return ContainerType.FILTERGUIDE;
            //    case 5 : return ContainerType.WEBSERVICE;
        default:
            return null;
        }
    }

    public static List<ContainerType> getContainerTypeList() throws IOException {

        int numItems = getInt("Number of container types (0): ", 0);

        List<ContainerType> list = null;
        if (numItems != 0) {
            list = new ArrayList<ContainerType>(numItems);

            for (int i = 0; i < numItems; i++) {
                list.add(getContainerType());
            }
        }

        return list;
    }

    public static LocalizedRequestInfo getLocalizedRequestInfo() throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("   Localized Message Request Info:\n");
        if (getBoolean("Null getLocalizedRequest Object? (F):", false)) {
            return null;
        }

        int id = 0;
        int workflowIfElse = 0;
        int workflowAction = 0;

        int messageType = getInt(" Message Type:  System, Active Link, Filter, Active Link Help,\n"
                + "   Form Help, Field Help, Container Desc., List Menu Defn,\n"
                + "   External Report ,Container Label, Application Help, \n"
                + "  Application About, Application Help Index   (0 - 13) (0): ", 0);

        String name = getString("     name: ", "");

        switch (messageType) {
        case Constants.AR_LOCAL_TEXT_FIELD_HELP:
        case Constants.AR_LOCAL_TEXT_EXTERN_REPORT:
            id = getInt("Internal ID (0): ", 0);
            break;

        case Constants.AR_LOCAL_TEXT_ACT_LINK_MESSAGE:
        case Constants.AR_LOCAL_TEXT_FILTER_MESSAGE:
            workflowIfElse = getInt("If/Else (0): ", 0);
            workflowAction = getInt("Action (0): ", 0);
            break;

        case Constants.AR_LOCAL_TEXT_SYSTEM_MESSAGE:
        case Constants.AR_LOCAL_TEXT_ACT_LINK_HELP:
        case Constants.AR_LOCAL_TEXT_FORM_HELP:
        case Constants.AR_LOCAL_TEXT_CONTAIN_DESC:
        case Constants.AR_LOCAL_TEXT_LIST_MENU_DEFN:

        default:
            break;
        }

        return new LocalizedRequestInfo(name, messageType, workflowIfElse, workflowAction, id);
    }

    public static LocalizedRequestInfo[] getLocalizedRequestInfoList() throws IOException {

        int numItems = getInt("Number of localized value operations (0): ", 0);

        LocalizedRequestInfo[] list = null;
        if (numItems != 0) {
            list = new LocalizedRequestInfo[numItems];

            for (int i = 0; i < numItems; i++) {
                list[i] = getLocalizedRequestInfo();
            }
        }

        return list;
    }

    public static StatusHistoryItem getStatusHistoryItem() throws IOException {
        JavaDriver.outputWriter.driverPrintPrompt("   Status History Info:\n");
        String user = getString("   User: ", "");
        Timestamp timestamp = new Timestamp(getLong("   TimeStamp(0): ", 0));

        return new StatusHistoryItem(user, timestamp);
    }

    public static StatusHistoryValue getStatusHistory() throws IOException {
        StatusHistoryValue value = new StatusHistoryValue();

        int numItems = getInt("Number of Status History Info Objects(0): ", 0);
        if (numItems != 0) {
            for (int i = 0; i < numItems; i++) {
                value.add(getStatusHistoryItem());
            }
        }
        return value;
    }

    public static DiaryItem getDiaryInfo() throws IOException {
        JavaDriver.outputWriter.driverPrintPrompt("   DiaryList Info:\n");
        String user = getString("   User: ", "");
        Timestamp timestamp = new Timestamp(getLong("   TimeStamp: ", 0));
        String diaryItemString = getString("     Text () ", "");

        return new DiaryItem(user, diaryItemString, timestamp);
    }

    public static DiaryListValue getDiaryInfoList() throws IOException {
        DiaryListValue list = new DiaryListValue();

        int numItems = getInt("Number of DiaryList Info Objects(0): ", 0);
        if (numItems != 0) {
            for (int i = 0; i < numItems; i++)
                list.add(getDiaryInfo());
        }
        return list;
    }

    public static EscalationTimeCriteria getEsclationTmInfo() throws IOException {

        if (getBoolean("Null EsclationTmInfo (F): ", false)) {
            return null;
        }

        EscalationTimeCriteria timeInfo = null;

        int type = getInt("Escalation Time Format (1-interval /2) (1) :", 1);

        if (type == 1) {
            long interval = getLong("Escalation Interval ( >0 ) (300):", 300);
            timeInfo = new EscalationInterval(interval);
        } else {
            DayInfo day = getDayInfo();
            timeInfo = new EscalationTime((int) day.getMonthday(), (int) day.getWeekday(), (int) day.getHourmask(),
                    (int) day.getMinute());
        }

        return timeInfo;
    }

    public static DayInfo getDayInfo() throws IOException {

        if (getBoolean("Null DayInfo (F): ", false)) {
            return null;
        }
        long day = getLong("Day (0):", 0);
        long hourMask = getLong("HourMask (0):", 0);
        long minutes = getLong("Minutes (0):", 0);
        long weekDay = getLong("Week day (0):", 0);

        return new DayInfo(day, weekDay, hourMask, minutes);
    }

    public static FieldLimit getFieldLimitInfo(int dataType) throws IOException, ARException {
        if (getBoolean("Set to NO LIMITS? (F): ", false)) {
            return null;
        }

        switch (dataType) {
        case Constants.AR_DATA_TYPE_INTEGER:
            return getIntegerLimitInfo();

        case Constants.AR_DATA_TYPE_REAL:
            return getRealLimitInfo();

        case Constants.AR_DATA_TYPE_CHAR:
            return getCharLimitInfo();

        case Constants.AR_DATA_TYPE_DIARY:
            return getDiaryLimitInfo();

        case Constants.AR_DATA_TYPE_TIME:
            return null;

        case Constants.AR_DATA_TYPE_ENUM:
            return getEnumLimitInfo();

        case Constants.AR_DATA_TYPE_BITMASK:
            return getEnumLimitInfo();

        case Constants.AR_DATA_TYPE_ATTACH:
            return getAttachmentLimitInfo();

        case Constants.AR_DATA_TYPE_DECIMAL:
            return getDecimalLimitInfo();

        case Constants.AR_DATA_TYPE_CURRENCY:
            return getCurrencyLimitInfo();

        case Constants.AR_DATA_TYPE_TABLE:
            return getTableLimitInfo();

        case Constants.AR_DATA_TYPE_COLUMN:
            return getColumnLimitInfo();

        case Constants.AR_DATA_TYPE_VIEW:
            return getViewLimits();

        case Constants.AR_DATA_TYPE_DISPLAY:
            return getDisplayLimits();

        default:
            return null;
        }
    }

    public static DataType getDataType() throws IOException {

        if (getBoolean("Null Data Type (F): ", false)) {
            return null;
        }

        JavaDriver.outputWriter
                .driverPrintPrompt("Datatype Null/Key/Int/Real/Char/DiaryList/Enum/Time/Bitmask/Byte/Decimal\n");

        int type = getInt(
                "    attach/currency/date/timeofday/join/trim/control/table/column/ulong/coords/view/display (0 - 14, 30-34, 40-43) (2): ",
                2);

        return DataType.toDataType(type);

    }

    public static FormType getFormType() throws IOException {

        if (getBoolean("Null Form Type (F): ", false)) {
            return null;
        }

        int type = getInt(
                "Type of form (all, regular, join, view, uplink, downlink, dialog, all_with_data, vendor) (0-8)(0):",
                0);

        switch (type) {
        case 0:
            return FormType.ALL;
        case 1:
            return FormType.REGULAR;
        case 2:
            return FormType.JOIN;
        case 3:
            return FormType.VIEW;
        case 4:
            return FormType.UPLINK;
        case 5:
            return FormType.DOWNLINK;
        case 6:
            return FormType.DIALOG;
        case 8:
            return FormType.VENDOR;
        case 7:
            return FormType.ALL_WITH_DATA;
        default:
            return null;
        }
    }

    public static EntryKey getEntryKey() throws IOException {

        if (getBoolean("Null Entry key (F): ", false)) {
            return null;
        }

        String formName = getString("Form Name (): ", "");
        int numItems = getInt("Number of Items in EntryId ? (1): ", 1);

        if (numItems <= 0) {
            return null;
        }

        String[] entryIDList = new String[numItems];

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < numItems; i++) {
            entryIDList[i] = getString("String: ", "");
            sb.append(entryIDList[i]);
            sb.append("|");
        }

        if (numItems == 1) {
            return new EntryKey(formName, entryIDList[0]);
        } else {
            String joinEntryID = sb.toString();
            joinEntryID = joinEntryID.substring(0, joinEntryID.length() - 1);
            return new EntryKey(formName, joinEntryID);
        }
    }

    public static ByteListValue[] getByteListInfoList() throws IOException {

        ByteListValue[] byteList = null;

        int numberOfValues = getInt("   Number of items (0): ", 0);

        if (numberOfValues != 0) {
            byteList = new ByteListValue[numberOfValues];

            for (int i = 0; i < numberOfValues; i++) {
                byteList[i] = getByteListInfo();
            }
        }

        return byteList;
    }

    public static Entry getEntry() throws IOException, ARException {

        Entry entry = new Entry();

        int numItems = getInt("  Number of Field/value pairs (0): ", 0);

        if (numItems != 0) {
            for (int i = 0; i < numItems; i++) {
                int fieldId = getInt("Field id (0): ", 0);
                Value val = getValue();
                entry.put(fieldId, val);
            }
        }

        return entry;
    }

    public static ViewKey getViewKey() throws IOException {

        if (getBoolean("Null ViewKey (F): ", false)) {
            return null;
        }

        // get the Form Name
        String formName = getString("Form Name (): ", "");

        // get the VUI id
        int vuiId = getInt("VUI id (1): ", 1);

        return new ViewKey(formName, vuiId);
    }

    public static int[] getIntArray() throws IOException {

        int[] fieldIdList = null;

        int numItems = getInt("   Number of field IDs (0): ", 0);

        if (numItems != 0) {
            fieldIdList = new int[numItems];
            for (int i = 0; i < numItems; i++) {
                fieldIdList[i] = getInt("Field id (0): ", 0);
            }
        }

        return fieldIdList;
    }

    public static QueryInfo getQueryInfo() throws IOException, ARException {

        if (getBoolean("Null QueryInfo (F): ", false)) {
            return null;
        }
        String form = getString("Form (): ", "");

        String server = getString("Server (): ", "");

        QualifierInfo qualifier = getQualifierInfo();

        int fieldId = getInt("Field id (0): ", 0);

        int multiMatchCode = getInt("Multi-Match code (error, first, set) (1, 2, 3) (1): ", 1);

        return new QueryInfo(form, server, qualifier, fieldId, multiMatchCode);

    }

    public static NotifyAction getNotifyActionInfo() throws IOException {

        if (getBoolean("Null NotifyActionInfo (F): ", false)) {
            return null;
        }

        NotifyAction info = new NotifyAction();

        JavaDriver.outputWriter.driverPrintHeader("Filter Action Notify (): ");

        int notifyMechanism = getInt("   Notifier, Email, Default, other, or XRef (1, 2, 3, 4-98, 99): ", 0);
        info.setNotifyMechanism(notifyMechanism);

        if (notifyMechanism == 99) {
            int ref = getInt("   Cross-reference field id: ", 0);
            info.setNotifyMechanismXRef(ref);
        }

        String user = getString("   User name: ", "");
        info.setUser(user);

        String text = getString("   Notify text (): ", "");
        info.setNotifyText(text);

        int notifyPriority = getInt("   Notify priority (1 to 10) (1): ", 1);
        info.setNotifyPriority(notifyPriority);

        String subject = getString("   Notify subject (): ", "");
        info.setSubjectText(subject);

        boolean isAdvanced = getBoolean("Is Advanced Notify Action (F): ", false);
        if (isAdvanced) {
            info.setFrom(getString("   From user: ", ""));
            info.setReplyTo(getString("   Reply To: ", ""));
            info.setCc(getString("   Cc user: ", ""));
            info.setBcc(getString("   Bcc user: ", ""));
            info.setOrganization(getString("   Organization: ", ""));
            info.setMailboxName(getString("   Mailbox name: ", ""));
            info.setHeaderTemplate(getString("   Header template: ", ""));
            info.setFooterTemplate(getString("   Footer template: ", ""));
            info.setContentTemplate(getString("   Content template: ", ""));
        }
        int fieldIdListType = getInt("   None, All, specific list, or changed (0, 1, 2, 3) (0): ", 0);
        info.setFieldIdListType(fieldIdListType);

        if (fieldIdListType == 2) {
            List<Integer> idList = getIntegerList();
            info.setFieldIdList(idList);
        }

        return info;
    }

    public static StatusInfo getStatusInfo() throws IOException {

        JavaDriver.outputWriter.driverPrintHeader("Status Info:");

        if (getBoolean("Null StatusInfo (F): ", false)) {
            return null;
        }

        int messageType = getInt("   Note, Warning, or Error (0, 1, 2) (2) : ", 2);
        long messageNum = getLong("   Message number (0): ", 0);
        String text = getString("   Message text (): ", "");
        String appendedText = getString("Appended Text():", "");

        return new StatusInfo(messageType, messageNum, text, appendedText);
    }

    public static CommitChangesAction getCommitChangesInfo() throws IOException {

        JavaDriver.outputWriter.driverPrintHeader("   Active Link Commit Changes Info :");

        if (getBoolean("Null CommitChangesInfo (F): ", false)) {
            return null;
        }

        String formName = getString("      Form Name (): ", "");

        return new CommitChangesAction(formName);
    }

    public static String getFileContents(String fileName) throws IOException, FileNotFoundException {

        File file = new File(fileName);
        FileReader fileReader = new FileReader(file);
        long length = file.length();
        char[] buffer = new char[(int) length + 1];
        String contents = null;

        if (fileReader.read(buffer, 0, (int) length) != length) {
            fileReader.close();
            JavaDriver.outputWriter.driverPrintWarning("Not able to read the entire file..\n");
            throw new IOException("Not able to read the entire file..\n");
        } else {
            contents = new String(buffer);
        }
        fileReader.close();
        return contents;
    }

    public static String getFileContent(String promt, String defaultFilePath, int numberOfAttempts,
            OutputWriter outputWriter) {
        String fileName = null;
        String content = null;
        for (int i = 0; i < numberOfAttempts; i++) {
            try {
                fileName = getString(promt, defaultFilePath);
                content = getFileContents(fileName);
            } catch (Throwable e) {
                outputWriter.printString(String.format("Could not read from given input file;%s\n",
                        (((i + 1) < numberOfAttempts) ? String.format("Retry (%d)...", i + 1) : "")));
            }
        }
        return content;
    }

    public static ReferenceType[] getReferenceTypeList() throws IOException {

        int numItems = getInt("   Number of reference types (0): ", 0);

        ReferenceType[] list = null;

        if (numItems != 0) {
            list = new ReferenceType[numItems];

            for (int i = 0; i < numItems; i++) {
                list[i] = getReferenceType();
            }
        }
        return list;
    }

    public static SupportFileKey getSupportFileKey() throws IOException {

        if (getBoolean("Null SupportFileKey? (F): ", false)) {
            return null;
        }

        int fileType = getInt("File type -- external report (1) (1):", 1);
        String name = getString("Name of associated object: ", "");
        int fieldID = getInt("Supporting ID for object (0):", 0);
        int fileID = getInt("ID for the file (1): ", 1);

        return new SupportFileKey(fileType, name, fieldID, fileID);
    }

    public static LocalizedValueCriteria getLocalizedValueCriteria() throws IOException {

        if (getBoolean("Null LocalizedValueCriteria? (F):", false)) {
            return null;
        }
        LocalizedValueCriteria criteria = new LocalizedValueCriteria();
        criteria.setRetrieveAll(false);

        if (getBooleanForChangingInfo("get Localized Values? (T): ", true))
            criteria.setPropertiesToRetrieve(LocalizedValueCriteria.VALUE | criteria.getPropertiesToRetrieve());

        if (getBooleanForChangingInfo("get Timestamps? (T): ", true))
            criteria.setPropertiesToRetrieve(LocalizedValueCriteria.TIMESTAMP | criteria.getPropertiesToRetrieve());

        return criteria;
    }

    public static AlertMessageCriteria getAlertMessageCriteria() throws IOException {

        AlertMessageCriteria criteria = new AlertMessageCriteria();
        criteria.setRetrieveAll(false);

        if (getBoolean("get Timestamp? (T): ", true)) {
            criteria.setPropertiesToRetrieve(AlertMessageCriteria.TIMESTAMP | criteria.getPropertiesToRetrieve());
        }

        if (getBoolean("get sourceType? (T): ", true)) {
            criteria.setPropertiesToRetrieve(AlertMessageCriteria.SOURCETYPE | criteria.getPropertiesToRetrieve());
        }

        if (getBoolean("get priority? (T): ", true)) {
            criteria.setPropertiesToRetrieve(AlertMessageCriteria.PRIORITY | criteria.getPropertiesToRetrieve());
        }

        if (getBoolean("get alertText? (T): ", true)) {
            criteria.setPropertiesToRetrieve(AlertMessageCriteria.ALERTTEXT | criteria.getPropertiesToRetrieve());
        }

        if (getBoolean("get sourceTag? (T): ", true)) {
            criteria.setPropertiesToRetrieve(AlertMessageCriteria.SOURCETAG | criteria.getPropertiesToRetrieve());
        }

        if (getBoolean("get serverName? (T): ", true)) {
            criteria.setPropertiesToRetrieve(AlertMessageCriteria.SERVERNAME | criteria.getPropertiesToRetrieve());
        }

        if (getBoolean("get serverAddress? (T): ", true)) {
            criteria.setPropertiesToRetrieve(AlertMessageCriteria.SERVERADDR | criteria.getPropertiesToRetrieve());
        }

        if (getBoolean("get formName? (T): ", true)) {
            criteria.setPropertiesToRetrieve(AlertMessageCriteria.FORMNAME | criteria.getPropertiesToRetrieve());
        }

        if (getBoolean("get objectId? (T): ", true)) {
            criteria.setPropertiesToRetrieve(AlertMessageCriteria.OBJECTID | criteria.getPropertiesToRetrieve());
        }

        return criteria;
    }

    public static String getString(String prompt) throws IOException {
        return getString(prompt, "");
    }

    public static JoinForm getJoinForm() throws IOException, ARException {
        if (getBoolean("Null JoinForm (F): ", false)) {
            return null;
        }
        String memberA = getString("Join member A name");
        String memberB = getString("Join member B name");
        QualifierInfo joinQual = getQualifierInfo();
        int option = getInt("   Join option(0): ", 0);

        return new JoinForm(memberA, memberB, joinQual, option);
    }

    public static ViewForm getViewForm() throws IOException {
        if (getBoolean("Null ViewForm (F): ", false)) {
            return null;
        }
        String tableName = getString("   View table name : ", "");
        String keyField = getString("   Key Field ");

        return new ViewForm(tableName, keyField);
    }

    public static VendorForm getVendorForm() throws IOException {
        if (getBoolean("Null VendorForm (F): ", false)) {
            return null;
        }

        String vendorName = getString("   Vendor name ");
        String vtableName = getString("   Vendor table name : ", "");

        return new VendorForm(vendorName, vtableName);
    }

    public static void openInputFile(String inputFileName) throws IOException {

        String fileName = null;
        if (inputFileName == null) {
            fileName = getString("File name of input file ()", "");
        } else {
            fileName = inputFileName;
        }

        if ((fileName == null) || (fileName.length() == 0)) {
            JavaDriver.outputWriter.driverPrintWarning("****No filename specified so no change to input file\n");
        } else {
            ThreadControlBlock threadControlBlockPtr = JavaDriver.getThreadControlBlockPtr();
            try {
                threadControlBlockPtr.setCurrentInputFile(fileName);
            } catch (FileNotFoundException e) {
                JavaDriver.outputWriter.printString("**** File error during open; no change to input file: "+fileName+"\n");
            }
        }
    }

    public static String[] getStringList() throws IOException {
        if (getBoolean("Null String List (F): ", false)) {
            return null;
        }

        String[] joinEntryList = null;

        int numEntries = getInt("Number Of Entries (1):", 1);
        if (numEntries > 0) {
            joinEntryList = new String[numEntries];
            for (int i = 0; i < numEntries; i++) {
                joinEntryList[i] = getString("", "");
            }
        }
        return joinEntryList;
    }

    public static WorkflowLockInfo getWorkflowLockInfo() throws IOException {
        if (getBoolean("Null WorkflowLockInfo (F): ", false)) {
            return null;
        }

        int lockType = getInt("   Lock type (0-None, 1-Read, 2-Hidden) (0): ", 0);
        String lockKey = null;

        if (lockType > 0) {
            lockKey = getString("   Lock Key: ");
        }

        return new WorkflowLockInfo(lockType, lockKey);
    }

    	public static WfdBreakpoint 
    WFDFillBreakPt(
    	boolean		local ) throws IOException 
    {

    	WfdBreakpoint bp = new WfdBreakpoint();

    	if( ! local ) {
    		bp.id = getInt("  BP location -\n  ID ? (0): ", 0);
    	}
    	bp.filter = getString("  Filter: ", "FilterName" );
    	bp.schema = getString("  Schema (*): ", "*" );
    	/*TODO: change to use a bitmask of stop points, rather than a specific stage?? */
    	bp.stage = Constants.WFD_BEFORE_QUAL + getInt("  Stage PreAPI/PreQual/Phase1/Phase2/Phase3/Escl/CMDB (0-5) (4): ", 1);
    	bp.elsePath = getBoolean("  Else path? (F): ", false );
    	bp.actionNo = getInt("  Action number (0): ", 0);
    	bp.disable = getBoolean("  Disabled (F): ", false);
    	bp.passcount = getInt("  Passcount ? (0): ", 0);
//TODO Since the qualifier isn't processed on the server yet,
// don't ask for it.
//    	if( (local == false) && (getBoolean("Add BP qualifier? (F): ", false)) )
//    	{
//    		if( getBoolean("Add BP qualifier? (F): ", false) )
//    			 bp.bpQualifier = getQualifierInfo( );
//    	}
//    	else
    	{
    		bp.bpQualifier = null;
    	}
    	return bp;
    }
    	
    public static RegularQuery getRegularQuery() throws IOException, ARException {
    	RegularQuery query = new RegularQuery();
    	
    	query.setFromSources(getQuerySourceList(""));    	
    	query.setFromFields(getQueryFormFieldList(query.getFromSources(), ""));
    	query.setQualifier(getQualifierInfo(query.getFromSources(), "Qualifier Info", ""));
    	query.setSortBy(getSortInfoList());
        return query;
    }

    public static RecursiveQuery getRecursiveQuery() throws IOException, ARException {
    	RecursiveQuery recQuery = new RecursiveQuery();
    	
    	recQuery.setFromSources(getQuerySourceList(recQuery, "      "));
    	recQuery.setFromFields(getQueryFormFieldList(recQuery.getFromSources(), "      "));
    	recQuery.setQualifier(getQualifierInfo(recQuery.getFromSources(), "Start qualifier", "      "));
    	
    	// recursion qualifier can select from the recursive query itself
		List<IQuerySource> recQualSources = new ArrayList<IQuerySource>(recQuery.getFromSources().size() + 1);
		recQualSources.addAll(recQuery.getFromSources());
		recQualSources.add(recQuery);
    	recQuery.setRecursionQualifier(getQualifierInfo(recQualSources, "Recursion qualifier", "      "));
    	
    	recQuery.setLevelsToRetrieve(getInt("      Levels to retrieve (0): ", 0));
    	
    	return recQuery;
    }
    
    public static List<IQuerySource> getQuerySourceList(String indent) throws IOException, ARException {
    	return getQuerySourceList(null, indent);
    }
    
    public static List<IQuerySource> getQuerySourceList(RecursiveQuery recQuery, 
    		String indent) throws IOException, ARException {
        List<IQuerySource> querySourceList = null;
        IQuerySource source = null;
        
        int numItems = getInt(indent + "Number of query sources (0): ", 0);
        if (numItems > 0) {
        	querySourceList = new ArrayList<IQuerySource>(numItems);
        	int i = 0;
        	while(i < numItems) {                        
            	source = getQuerySource(indent, recQuery, i == 0 ? null : querySourceList);
            	
            	if(source != null) {
            		querySourceList.add(source);
            		i++;
            	}
            }
        }

        return querySourceList;
    }
    
    public static IQuerySource getQuerySource(String indent, RecursiveQuery recQuery, 
    		List<IQuerySource> joinableSources) throws IOException, ARException {    	
    	JavaDriver.outputWriter.driverPrintPrompt(indent + "    Query source: \n");
    	IQuerySource querySource = null;
    	boolean recurseOn = false;
    	
    	int sourceType;
    	if(recQuery == null) {
    		sourceType = getInt(indent + "      Type: Form name, Nested, Recursive (0 - 2) (0): ", 0);    		
    	}
    	else // recursive query contains forms only
    		sourceType = 0;
    	
    	// form
    	if(sourceType == 0) {
    		querySource = new QuerySourceForm(getString(indent + "      Form: ", ""));
    		if(recQuery != null && !recurseOn) {
    			recurseOn = getBoolean(indent + "      Recurse on this form (T): ", true);
    			if(recurseOn)
    				recQuery.setRecursiveForm((QuerySourceForm)querySource);
    		}    			
    	}    	
    	// recursive
    	else if (sourceType == 2) {
    		querySource = getRecursiveQuery();    		
    	}
    	// nested
    	else {
    		JavaDriver.outputWriter.driverPrintWarning("****This query type is not supported\n"); 
    		return null;
    	}
    	    	
    	if(querySource!= null && joinableSources != null && joinableSources.size() > 0) {
    		List<IQuerySource> qualifierSources = new ArrayList<IQuerySource>(joinableSources.size() + 1);
    		qualifierSources.addAll(joinableSources);
    		qualifierSources.add(querySource);
    		querySource.setJoinType(getInt(indent + "      Join type: Inner, Left, Right (0 - 2) (0): ", 0));
    		querySource.setJoinQualifier(getQualifierInfo(qualifierSources, "Join qualifier", indent + "      "));
    		querySource.setJoinedWith(getSourceJoinedWith(joinableSources, indent + "      "));    		
    	}
    	
        return querySource;
    }
    
    public static IQuerySource getSourceJoinedWith(List<IQuerySource> sources, 
    		String indent) throws IOException {
        int idx = getInt(indent +  "Joined with (" + getQuerySourcesPrompt(sources) + ") (0): ", 0);        
        
        return sources.get(idx);
    }
    
    public static List<QueryFormField> getQueryFormFieldList(List<IQuerySource> sources, 
    		String indent) throws IOException {
        List<QueryFormField> queryFromFieldList = null;

        int numItems = getInt(indent + "Number of query fields (0): ", 0);
        if (numItems > 0) {
        	queryFromFieldList = new ArrayList<QueryFormField>(numItems);        	
            for (int i = 0; i < numItems; i++) {
            	queryFromFieldList.add(getQueryFormField(sources, indent));
            }
        }

        return queryFromFieldList;
    }
    
    public static QueryFormField getQueryFormField(List<IQuerySource> sources, 
    		String indent) throws IOException {
        QueryFormField queryFromField = new QueryFormField();        
        
        JavaDriver.outputWriter.driverPrintPrompt(indent + "    Query field: \n");
        
        queryFromField.setFieldId(getInt(indent + "      Field id (0): ", 0));

        int idx = getInt(indent +  "      Field source (" + getQuerySourcesPrompt(sources) + ") (0): ", 0);        
        queryFromField.setSource(sources.get(idx));
        
        return queryFromField;
    }
    
    public static ValueSetQuery getValueSetQuery(String indent) throws IOException, ARException {
    	List<QueryFormField> queryFromFieldList = new ArrayList<QueryFormField>(1);
    	ValueSetQuery query = new ValueSetQuery();
    	
    	query.setFromSources(getQuerySourceList(indent));
    	queryFromFieldList.add(getQueryFormField(query.getFromSources(), indent));
    	query.setFromFields(queryFromFieldList);
    	query.setQualifier(getQualifierInfo(query.getFromSources(), "Qualifier Info", indent));
    	
    	return query;
    }
    
    private static String getQuerySourcesPrompt(List<IQuerySource> sources) throws IOException {
    	String sourceList = "";
    	
        for(int i = 0; i < sources.size(); i++) {        	
        	if(sources.get(i) instanceof RecursiveQuery)
        		sourceList += "Recursive query - " + i + ", ";
        	else if(sources.get(i) instanceof QuerySourceForm)
        		sourceList += ((QuerySourceForm)sources.get(i)).getName() + "(" + i + "), ";
        }
        
        if(sourceList.endsWith(", "))
        	sourceList = sourceList.substring(0, sourceList.length() - 2);
        
        return sourceList;
    }
    
    /**
     * Check if the string is a valid decimal value format
     * @param value
     * @return
     * @throws ARException
     */
    private static void checkDecimalFormat(String value) throws ARException {
        CurrencyValue.checkDecimalFormat(value);
    }
    /**
     * Method to gather Details of Image File( image data)
     * @return
     * @throws IOException
     */
    public static ImageData getImageData()  throws IOException{
        int option = getInt("Choose:\n   1 - prompt for filename \n   2 - prompt for string\n default (1): ", 1);
        ImageData data = null;
        switch (option) {
        case 1:
            String filename = getString("Image File name (): ", "");
            data = new ImageData(filename);
            break;
        case 2:
            int length = getInt("Number of Items in the List (0): ", 0);
            byte[] byteBuffer = new byte[1024];
            char[] charBuffer = new char[length];
            for (int i = 0; i < length; i++) {
                charBuffer[i] = getChar("Byte[" + i + "]", ' ');
            }
            byteBuffer = charBuffer.toString().getBytes();
            data = new ImageData(byteBuffer);
            break;
        }
        return data;
    }
    
    public static String[] getObjectModificationLogLabelAndTaskName() throws IOException {
        String[] rst = new String[1];
        rst[0] = getString("Object Modification Log Label (): ", "");
        if (rst[0].length() == 0) /* "" is not a valid label */
            rst[0] = null;
/*        rst[1] = getString("TaskName (): ", "");
        if (rst[1].length() == 0) / * "" is not a valid taskName * /
            rst[1] = null;
*/
        return rst;
    }
}
