/*****************************************************************************/
/*                                                                           */
/*                                                                           */
/*   ©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.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
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());
        serverUser.setClientType(Constants.AR_CLIENT_TYPE_DRIVER);

        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 = getDouble(indent + "Real Value (0.0): ", 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);
        String description = getString("Description: ");
        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.setDescription(description);
        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);
        boolean appearInArchivePolicy = getBooleanForChangingInfo("Appear In Archive Policy If Unscheduled<T> : ", true);
        archive.setAppearInArchivePolicy(appearInArchivePolicy);
        return archive;
    }

    public static AssociationsToFollow getAssociationsToFollow() throws IOException, ARException {
        int selectionType = getInt("Selection Type (None-0, Specific Only -1, All Enforced - 2, All - 3) ? : ", 0);
        List<String> spcfcAssocsNames = InputReader.getStringList("", "Specific Association Names : ");
        AssociationsToFollow assocsToFollow = new AssociationsToFollow(AssociationSelectionType.getEnumValue(selectionType),
                spcfcAssocsNames);
        return assocsToFollow;
    }

    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 Association getAssociation(int type) throws IOException, ARException {

        switch (type) {
            case Constants.AR_ASSOCIATION_TYPE_DIRECT:
                return getDirectAssociation();
            case Constants.AR_ASSOCIATION_TYPE_INDIRECT:
                return getIndirectAssociation();
            default:
                return getDirectAssociation();
        }
    }

    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 FieldKey getFieldKey(String prompt) throws IOException {
        JavaDriver.outputWriter.driverPrintPrompt(prompt);

        if (getBoolean("Null Field Key (F)", false)) {
            return null;
        }

        String formName = getString("       Form Name:");
        int fieldId = getInt("       Field ID (0):", 0);

        return new FieldKey(formName, fieldId);
    }

    public static PKFKMapping getPKFKMapping() throws IOException {
        JavaDriver.outputWriter.driverPrintPrompt(" PKFK Mapping : \n");

        if (getBoolean("Null PKFK Mapping (F)", false)) {
            return null;
        }

        int pKey = getInt(" Primary Key Field : \n", 0);
        int fKey = getInt(" Foreign Key Field : \n", 0);

        return new PKFKMapping(pKey, fKey);

    }

    public static Set<PKFKMapping> getPKFKMappingSet() throws IOException {
        JavaDriver.outputWriter.driverPrintPrompt("PKFK Mapping Set:\n");

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

        Set<PKFKMapping> pkfkMappingSet = null;

        if (numItems != 0) {
            pkfkMappingSet = new HashSet<PKFKMapping>(numItems);
            for (int i = 0; i < numItems; i++) {
                pkfkMappingSet.add(getPKFKMapping());
            }
        }
        return pkfkMappingSet;
    }

    private static AssociationFormKeyMapping getAssociationFormKeyMapping() throws IOException {

        JavaDriver.outputWriter.driverPrintPrompt("Mapping Between Primary Form And Association Form, ");
        Set<PKFKMapping> pkfkMappingBetweenPrimaryAndExternal = getPKFKMappingSet();
        JavaDriver.outputWriter.driverPrintPrompt("Mapping Between Secondary Form And Association Form, ");
        Set<PKFKMapping> pkfkMappingBetweenSecondaryAndExternal = getPKFKMappingSet();

        return new AssociationFormKeyMapping(pkfkMappingBetweenPrimaryAndExternal,
                pkfkMappingBetweenSecondaryAndExternal);
    }

    public static RealFieldLimit getRealLimitInfo() throws IOException {

        if (getBoolean("Null RealLimitInfo (F): ", false)) {
            return null;
        }
        double rangeLow = getDouble("   Real range low (0): ", 0);
        double rangeHigh = getDouble("   Real range high (5000): ", 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 = 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 = 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 = getCharMenuListInfo();
                break;
            case Constants.AR_CHAR_MENU_QUERY:
                menu = getCharMenuQueryInfo();
                break;
            case Constants.AR_CHAR_MENU_FILE:
                menu = getCharMenuFileInfo();
                break;
            case Constants.AR_CHAR_MENU_SQL:
                menu = getCharMenuSQLInfo();
                break;
            case Constants.AR_CHAR_MENU_DATA_DICTIONARY:
                menu = getCharMenuDDInfo();
            case Constants.AR_CHAR_MENU_SS:
                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,image,association (0,2-8, 10) (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, allowed_mfsearch, fts_scan_time,archive_downlink) (0-11)(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 7:
                return FormType.ALL_WITH_DATA;
            case 8:
                return FormType.VENDOR;
            case 9:
                return FormType.ALLOWED_IN_MFSEARCH;
            case 10:
                return FormType.FTS_SCAN_TIME;
            case 11:
                return FormType.ARCHIVE_DOWNLINK;
            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 DirectAssociation getDirectAssociation() throws IOException, ARException {
        if (getBoolean("Null Direct Association(F): ", false)) {
            return null;
        }

        Set<PKFKMapping> pkfkMappingSet = getPKFKMappingSet();
        DirectAssociation directAssoc = new DirectAssociation();
        directAssoc.setPkfkMappingSet(pkfkMappingSet);

        return directAssoc;
    }

    public static IndirectAssociation getIndirectAssociation() throws IOException, ARException {
        if (getBoolean("Null Indirect Association (F): ", false)) {
            return null;
        }

        IndirectAssociation indirectAssoc = new IndirectAssociation();
        AssociationFormKeyMapping associationFormKeyMapping = getAssociationFormKeyMapping();
        indirectAssoc.setKeyMappingToAssociationForm(associationFormKeyMapping);
        return indirectAssoc;
    }

    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) {
            rst[0] = null;
        }
        /*        rst[1] = getString("TaskName (): ", "");
                if (rst[1].length() == 0) / * "" is not a valid taskName * /
                    rst[1] = null;
         */
        return rst;
    }
}
