All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.quinsoft.zeidon.vml.VmlOperation Maven / Gradle / Ivy

/**
    This file is part of the Zeidon Java Object Engine (Zeidon JOE).

    Zeidon JOE is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Zeidon JOE is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Zeidon JOE.  If not, see .

    Copyright 2009-2015 QuinSoft
 */

package com.quinsoft.zeidon.vml;

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.mutable.MutableDouble;
import org.apache.commons.lang3.mutable.MutableInt;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.quinsoft.zeidon.ActivateFlags;
import com.quinsoft.zeidon.Application;
import com.quinsoft.zeidon.AttributeInstance;
import com.quinsoft.zeidon.CursorPosition;
import com.quinsoft.zeidon.CursorResult;
import com.quinsoft.zeidon.DeserializeOi;
import com.quinsoft.zeidon.EntityCursor;
import com.quinsoft.zeidon.EntityInstance;
import com.quinsoft.zeidon.InvalidViewException;
import com.quinsoft.zeidon.ObjectConstraintException;
import com.quinsoft.zeidon.SelectSet;
import com.quinsoft.zeidon.SetMatchingFlags;
import com.quinsoft.zeidon.Task;
import com.quinsoft.zeidon.TaskQualification;
import com.quinsoft.zeidon.UnknownAttributeDefException;
import com.quinsoft.zeidon.UnknownEntityDefException;
import com.quinsoft.zeidon.UnknownLodDefException;
import com.quinsoft.zeidon.View;
import com.quinsoft.zeidon.WriteOiFlags;
import com.quinsoft.zeidon.ZeidonException;
import com.quinsoft.zeidon.domains.TableDomain;
import com.quinsoft.zeidon.domains.TableEntry;
import com.quinsoft.zeidon.objectdefinition.AttributeDef;
import com.quinsoft.zeidon.objectdefinition.EntityDef;
import com.quinsoft.zeidon.objectdefinition.LodDef;
import com.quinsoft.zeidon.standardoe.IncrementalEntityFlags;
import com.quinsoft.zeidon.utils.JoeUtils;
import com.quinsoft.zeidon.utils.QualificationBuilder;

import net.htmlparser.jericho.Attribute;
import net.htmlparser.jericho.CharacterReference;
import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.EndTagType;
import net.htmlparser.jericho.HTMLElementName;
import net.htmlparser.jericho.HTMLElements;
import net.htmlparser.jericho.OutputDocument;
import net.htmlparser.jericho.Segment;
import net.htmlparser.jericho.Source;
import net.htmlparser.jericho.StartTag;
import net.htmlparser.jericho.StartTagType;
import net.htmlparser.jericho.Tag;

/*
//package org.kodejava.example.lowagie;

import com.itextpdf.text.*;
//import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.BaseFont;
*/

//import com.quinsoft.zeidon.vml.VmlDialog.MemoryItem;
//import com.quinsoft.zeidon.vml.VmlDialog.MemoryList;
//import com.quinsoft.zeidon.vml.VmlDialog.ZHTML_Attribute;
//import com.quinsoft.zeidon.vml.VmlDialog.ZHTML_Parse;
//import com.quinsoft.zeidon.vml.VmlDialog.ZHTML_ParseHTML;
//import com.quinsoft.zeidon.vml.VmlDialog.ZHTML_TagAttributeList;
//import com.quinsoft.zeidon.vml.VmlDialog.ZNameItem;

/**
 * This is a helper class for Java code generated from VML.  It has some standard
 * "operations" defined so that the generated java can look similar to the generated C.
 *
 * Code that is generated from VML should extend this class.
 *
 * @author DG
 *
 */

// public static boolean isEmpty(String str)  Checks if a String is empty ("") or null.

// StringUtils.isEmpty(null) = true
// StringUtils.isEmpty("") = true
// StringUtils.isEmpty(" ") = false
// StringUtils.isEmpty(" bob ") = false

// public static boolean isBlank(String str)  Checks if a String is whitespace, empty ("") or null.
// StringUtils.isBlank(null) = true
// StringUtils.isBlank("") = true
// StringUtils.isBlank(" ") = true
// StringUtils.isBlank(" bob ") = false

public abstract class VmlOperation
{
   Object lockMessage = new Object();

   public static final int zLEVEL_SUBTASK     = 1;
   public static final int zLEVEL_TASK        = 2;
   public static final int zLEVEL_APPLICATION = 4;
   public static final int zLEVEL_SYSTEM      = 8;
   public static final int zLEVEL_ALL         = 255;
   public static final int zLEVEL_ANY         = 15;
   public static final int zNAME_AUTODROP     = 64;

   public static final int zOCE_ACTIVATE       = 1;
   public static final int zOCE_ACTIVATE_EMPTY = 2;
   public static final int zOCE_COMMIT         = 3;
   public static final int zOCE_DROPOI         = 4;

   public static final int zSET_NULL       = 0x00000000;
   public static final int zSET_KEYS       = 0x00000001;
   public static final int zSET_NOTNULL    = 0x00000002;
   public static final int zSET_SRCNOTNULL = 0x00000004;
   public static final int zSET_ALL        = zSET_NULL | zSET_KEYS | zSET_NOTNULL;

   public static final int zPOS_NONE   = 0;
   public static final int zPOS_FIRST  = 1;
   public static final int zPOS_LAST   = 2;
   public static final int zPOS_NEXT   = 3;
   public static final int zPOS_AFTER  = 3;
   public static final int zPOS_PREV   = 4;
   public static final int zPOS_BEFORE = 4;

   public static final int zREPOS_NONE   = 0;
   public static final int zREPOS_FIRST  = 1;
   public static final int zREPOS_LAST   = 2;
   public static final int zREPOS_AFTER  = 3;
   public static final int zREPOS_NEXT   = 3;
   public static final int zREPOS_BEFORE = 4;
   public static final int zREPOS_PREV   = 4;

   public static final int zSET_INCR_CREATED          = 2;
   public static final int zSET_INCR_PERSISTENT       = 4;
   public static final int zSET_INCR_UPDATED          = 8;
   public static final int zSET_INCR_NOT_UPDATED      = 16;
   public static final int zSET_INCR_INCLUDED         = 32;
   public static final int zSET_INCR_EXCLUDED         = 0;  // undefined in C version
   public static final int zSET_INCR_HIDDEN           = 1;  // undefined in C version
   public static final int zSET_INCR_NOT_INCLUDED     = 64;
   public static final int zSET_INCR_CURSORPOS        = 128;
   public static final int zSET_INCR_HANGING_ENTITY   = 2048;
   public static final int zSET_INCR_TEMPORAL_ENTITY  = 16384;
   public static final int zSET_INCR_DELETED          = 32768;
   public static final int zSET_INCR_ATTR_UPDATED     = 4096;
   public static final int zSET_INCR_ATTR_NOT_UPDATED = 8192;

   public static final int zCOMMIT_NOCLEANUP          = 256;      // 0x00000100L
   public static final int zCOMMIT_FORCETRAN          = 1024;     // 0x00000400L
   public static final int zCOMMIT_DROPLOCKSONLY      = 2048;     // 0x00000800L
   public static final int zCOMMIT_KEEPLOCKS          = 4096;     // 0x00001000L
   public static final int zCOMMIT_DROPVIEW           = 8192;     // 0x00002000L
   public static final int zCOMMIT_DROPOBJECTINSTANCE = 16384;    // 0x00004000L
   public static final int zCOMMIT_NOCONSTRAINTS      = 16777216; // 0x01000000L

   public static final int zASCII                     = 0;        // 0x00000000L
   public static final int zINCREMENTAL               = 65536;    // 0x00010000L
   public static final int zCOMPRESSED                = 131072;   // 0x00020000L  // Store in compressed form.
   public static final int zSAVE_CURSORS              = 262144;   // 0x00040000L  // Save cursor positions.
   public static final int zENTITY_TAGS               = 524288;   // 0x00080000L  // Write entity tags (pointers).
   public static final int zWRITE_KEYS_ONLY           = 1048576;  // 0x00100000L  // Write key attrs only.
   public static final int zENTITY_KEYS               = 2097152;  // 0x00200000L  // Write entity keys.
   public static final int zENCODE_BLOBS              = 4194304;  // 0x00400000L  // Encode blobs from binary to ASCII
   public static final int zNO_NULL_STRING_TERM       = 8388608;  // 0x00800000L  // Don't use null terminator for strings

   /**
    * A map to convert C-style cursor positions (int) to JOE-style (enum).
    */
   private static final Map CURSOR_POS =
       Collections.unmodifiableMap( new HashMap() {
       private static final long serialVersionUID = 1L;
   {
       put( zREPOS_NONE,  CursorPosition.NONE  );
       put( zREPOS_FIRST, CursorPosition.FIRST );
       put( zREPOS_LAST,  CursorPosition.LAST  );
       put( zREPOS_NEXT,  CursorPosition.NEXT  );
       put( zREPOS_PREV,  CursorPosition.PREV  );
   }} );

   public static final int TRUE  = 1;
   public static final int FALSE = 0;

   public static final char zTYPE_STRING = 'S';
   public static final char zTYPE_INTEGER = 'L';
   public static final char zTYPE_DECIMAL = 'M';
   public static final char zTYPE_BLOB = 'B';
   public static final char zTYPE_DATETIME = 'T';
   public static final char zTYPE_PIC = 'P';
   public static final char zTYPE_FIXEDCHAR = 'F';

   public static final int zDERIVED_SET = AttributeDef.DERIVED_SET;
   public static final int zDERIVED_GET = AttributeDef.DERIVED_GET;

   public static final int zCURSOR_SET = CursorResult.SET.toInt();
   public static final int zCURSOR_UNCHANGED = CursorResult.UNCHANGED.toInt();
   public static final int zCURSOR_NULL = CursorResult.NULL.toInt();
   public static final int zCURSOR_UNDEFINED = CursorResult.NULL.toInt();
   public static final int zCURSOR_SET_RECURSIVECHILD = CursorResult.SET_RECURSIVE_CHILD.toInt();
   public static final int zCURSOR_SET_NEWPARENT = CursorResult.SET_NEWPARENT.toInt();

   public static final int zCONTROL_STATUS_ENABLED               = 1;
   public static final int zCONTROL_STATUS_CHECKED               = 2;
   public static final int zCONTROL_STATUS_VISIBLE               = 3;
   public static final int zCONTROL_STATUS_BACKGROUND_COLOR      = 4;
   public static final int zCONTROL_STATUS_TEXT_COLOR            = 5;
   public static final int zCONTROL_STATUS_FONT                  = 6;
   public static final int zCONTROL_STATUS_ENTER                 = 7;
   public static final int zCONTROL_STATUS_ERROR                 = 8;
   public static final int zCONTROL_STATUS_AUTOGRAY              = 9;
   public static final int zCONTROL_STATUS_TOPMOST               = 10;
   public static final int zCONTROL_STATUS_BOTTOMMOST            = 11;
   public static final int zCONTROL_STATUS_HWND                  = 12;
   public static final int zCONTROL_STATUS_AUTOMAP_FROM_OI       = 13;
   public static final int zCONTROL_STATUS_AUTOMAP_TO_OI         = 14;
   public static final int zCONTROL_STATUS_DISABLE_READONLY      = 15;
   public static final int zCONTROL_STATUS_REPAINT               = 16;
   public static final int zCONTROL_STATUS_MARK_READONLY_ENABLED = 17;
   public static final int zCONTROL_STATUS_ENABLE_TABSTOP        = 18;
   public static final int zCONTROL_STATUS_SELECT_INDEX          = 19;
   public static final int zCONTROL_STATUS_ABSOLUTE_PIXEL_SIZE   = 20;
   public static final int zCONTROL_STATUS_ABSOLUTE_PIXEL_POS    = 21;
   public static final int zCONTROL_STATUS_HASBUTTONS            = 22;
   public static final int zCONTROL_STATUS_HASLINES              = 23;
   public static final int zCONTROL_STATUS_LINESATROOT           = 24;
   public static final int zCONTROL_STATUS_DISABLEDRAGDROP       = 25;
   public static final int zCONTROL_STATUS_NOSHOW_ENTITY         = 26;
   public static final int zCONTROL_STATUS_MULTIPLEROOT          = 27;
   public static final int zCONTROL_STATUS_MULTISELECT           = 28;
   public static final int zCONTROL_STATUS_SINGLEEXPAND          = 29;
   public static final int zCONTROL_STATUS_EXPAND                = 30;
   public static final int zCONTROL_STATUS_EXPANDALL             = 31;
   public static final int zCONTROL_STATUS_MAP_ERROR             = 32;
   public static final int zCONTROL_STATUS_SELECT_ALL            = 33;
   public static final int zCONTROL_STATUS_RESET                 = 34;
   public static final int zCONTROL_STATUS_CREATED               = 35;
   public static final int zCONTROL_STATUS_MAPPED                = 36;

// protected static final Set zSINGLE   = ActivateFlags.SINGLE;
// protected static final Set zMULTIPLE = ActivateFlags.MULTIPLE;
// protected static final Set zACTIVATE_ROOTONLY_MULTIPLE = ActivateFlags.ROOT_ONLY_MULTIPLE;
// protected static final Set zACTIVATE_ROOTONLY = ActivateFlags.ROOT_ONLY_MULTIPLE;
// protected static final Set zIGNORE_ENTITY_ERRORS = ActivateFlags.IGNORE_ENTITY_ERRORS;
// protected static final Set zIGNORE_ATTRIB_ERRORS = ActivateFlags.IGNORE_ATTRIB_ERRORS;
// protected static final Set zIGNORE_ERRORS = ActivateFlags.IGNORE_ERRORS;
// protected static final Set zSINGLE_FOR_UPDATE = ActivateFlags.SINGLE;

   public static final int zICON_ERROR = 0;
   public static final int zICON_QUESTION = 0;
   public static final int zEXPANDALL = 0;

   public static final int zSINGLE                 = 0;          // 0x00000000L
   public static final int zAPPLICATION            = 4;          // 0x00000004L
   public static final int zMULTIPLE               = 256;        // 0x00000100L
   public static final int zNOI_OKAY               = 512;        // 0x00000200L
   public static final int zNOENQUEUE              = 1024;       // 0x00000400L
   public static final int zREADONLY               = 2048;       // 0x00000800L
   public static final int zIGNORE_ENTITY_ERRORS   = 4096;       // 0x00001000L
   public static final int zIGNORE_ATTRIB_ERRORS   = 8192;       // 0x00002000L
   public static final int zIGNORE_ERRORS          = 12288;      // 0x00003000L
   public static final int zACTIVATE_OPTION        = 16384;      // 0x00004000L
   public static final int zACTIVATE_OPTION2       = 32768;      // 0x00008000L
   public static final int zACTIVATE_NOCONSTRAINTS = 16777216;   // 0x01000000L
   public static final int zNEW_OBJECT_NAME        = 33554432;   // 0x02000000L
   public static final int zSINGLE_FOR_UPDATE      = 67108864;   // 0x04000000L
   public static final int zACTIVATE_CONTINUE      = 134217728;  // 0x08000000L
   public static final int zACTIVATE_LOCAL         = 1073741824; // 0x40000000L
   public static final int zACTIVATE_SYSTEM        = 536870912;  // 0x20000000L
   public static final int zACTIVATE_ROOTONLY      = 268435456;  // 0x10000000L
   public static final int zACTIVATE_ROOTONLY_MULTIPLE = 268435712;  // 0x10000000L + 0x00000100L
   public static final int zIGNORE_JOINS           = 1048576;    // 0x00100000L
   public static final int zASYNCHRONOUS           = 2097152;    // 0x00200000L

   /**
    * A map to convert C-style activate flags (int) to JOE-style (enum).
    */
   private static final Map> ACTIVATE_CONTROL =
       Collections.unmodifiableMap( new HashMap>() {
       private static final long serialVersionUID = 2L;
   {
       put( zSINGLE, ActivateFlags.SINGLE );
       put( zMULTIPLE, ActivateFlags.MULTIPLE );
       put( zACTIVATE_ROOTONLY_MULTIPLE, ActivateFlags.ROOT_ONLY_MULTIPLE );
       put( zACTIVATE_ROOTONLY, ActivateFlags.ROOT_ONLY );
       put( zIGNORE_ENTITY_ERRORS, ActivateFlags.IGNORE_ENTITY_ERRORS );
       put( zIGNORE_ATTRIB_ERRORS, ActivateFlags.IGNORE_ATTRIB_ERRORS );
       put( zIGNORE_ERRORS, ActivateFlags.IGNORE_ERRORS );
       put( zSINGLE_FOR_UPDATE, ActivateFlags.SINGLE );
       put( zIGNORE_JOINS, ActivateFlags.IGNORE_JOINS );
       put( zASYNCHRONOUS, ActivateFlags.ASYNCHRONOUS );

       // Ignore zAPPLICATION whan paired with SINGLE
       put( zSINGLE + zAPPLICATION, ActivateFlags.SINGLE );
   }} );

   /**
    * A map to convert C-style incremental flags (int) to JOE-style (enum).
    */

   private static final Map> SET_INCREMENTAL =
       Collections.unmodifiableMap( new HashMap>() {
       private static final long serialVersionUID = 3L;
   {
       put( zSET_INCR_CREATED, IncrementalEntityFlags.CREATED );
       put( zSET_INCR_UPDATED, IncrementalEntityFlags.UPDATED );
       put( zSET_INCR_DELETED, IncrementalEntityFlags.DELETED );
       put( zSET_INCR_EXCLUDED, IncrementalEntityFlags.EXCLUDED );
       put( zSET_INCR_INCLUDED, IncrementalEntityFlags.INCLUDED );
       put( zSET_INCR_HIDDEN, IncrementalEntityFlags.HIDDEN  );
   }} );

   public static final String zNEW_LINE = "\n";
   public static final String NEW_LINE = "\n";
   public static final String zQUOTES = "\"";
   public static final String QUOTES = "\"";
   public static final String zTAB = "\t";

   public static final int zQUAL_EQUAL = 16;
   public static final int zQUAL_GREATER_THAN = 32;
   public static final int zQUAL_LESS_THAN = 64;
   public static final int zQUAL_NOT = 128;
   public static final int zQUAL_OPERATOR = 240;
   public static final int zQUAL_INTEGER = 256;
   public static final int zQUAL_DECIMAL = 512;
   public static final int zQUAL_STRING = 1024;
   public static final int zQUAL_DATETIME = 2048;
   public static final int zQUAL_ENTITYATTR = 4096;
   public static final int zQUAL_ENTITYCSR = 2097152;  // 0x00200000L
   public static final int zQUAL_ENTITYKEY = 8388608;  // 0x00800000L
   public static final int zQUAL_ATTR_NULL = 32768;  // 0x00008000L
   public static final int zQUAL_ATTR_HIDDEN = 16777216;  // 0x01000000L
   public static final int zQUAL_OPERAND = 40704;  // 0x00009F00L
   public static final int zQUAL_SELECTED = 8192;  // 0x00002000L
   public static final int zQUAL_UNSELECTED = 16384;  // 0x00004000L
   public static final int zTEST_CSR_RESULT = 65536;  // 0x00010000L
   public static final int zRECURS = 131072;  // 0x00020000L
   public static final int zQUAL_ZKEYS = 262144;  // 0x00040000L
   public static final int zQUAL_SCOPE_OI = 524288;  // 0x00080000L
   public static final int zSPARENT_KEEPCHILDREN = 1048576;  // 0x00100000L
   public static final int zIGNORE_ERROR_358 = 4194304;  // 0x00400000L
   public static final int zLBITS = -1;  // 0xFFFFFFFFL

   public static final int zUSE_DEFAULT_CONTEXT = 8;
   public static final int zACCEPT_NULL_ENTITY  = 1;
   public static final int zVALIDATE = 4;
   public static final int zIGNORE_KEYS = 16;
   public static final int zUSE_TASK = 4096;

   public static final int COREFILE_READ = 128;              // 0x0080;
   public static final int COREFILE_WRITE = 64;              // 0x0040;
   public static final int COREFILE_UPDATE = 192;            // (COREFILE_READ | COREFILE_WRITE);
   public static final int COREFILE_CREATE = 32;             // 0x0020;
   public static final int COREFILE_DELETE = 8;              // 0x0008;
   public static final int COREFILE_RENAME = 16;             // 0x0010;
   public static final int COREFILE_EXIST = 4;               // 0x0004;
   public static final int COREFILE_EXISTS = 4;              // 0x0004;
   public static final int COREFILE_WRITELINE_BUFFERED = 1;  // 0x0001;
   public static final int COREFILE_APPEND = 448;            // (0x0100 | COREFILE_UPDATE);
   public static final int COREFILE_BACKUP = 4096;           // 0x1000;
   public static final int COREFILE_CREATE_NEW = 562;        // (0x0200 | COREFILE_CREATE);

   public static final int zREPORT_PRINTREMOTE = 131072;     // 0x00020000

   public static final int zAPPL_NAME = 0;
   public static final int zAPPL_DIR_LIB = 1;
   public static final int zAPPL_DIR_OBJECT = 2;
   public static final int zAPPL_DIR_LOCAL = 3;
   public static final int zAPPL_DIR_SHARED = 4;
   public static final int zAPPL_DIR_QLPLR = 5;
   public static final int zAPPL_DIR_SOURCE = 6;

   protected static final int zBUTTONS_YESNO = 1;
   protected static final int zBUTTONS_YESNOCANCEL = 2;
   protected static final int zBUTTONS_OK = 3;
   protected static final int zBUTTONS_OKCANCEL = 4;
   protected static final int zBUTTONS_RETRYCANCEL = 5;
   protected static final int zBUTTONS_ABORTRETRYIGNORE = 6;

   protected static final int zRESPONSE_YES = 1;
   protected static final int zRESPONSE_NO = 2;
   protected static final int zRESPONSE_CANCEL = 3;
   protected static final int zRESPONSE_OK = 4;
   protected static final int zRESPONSE_ABORT = 5;
   protected static final int zRESPONSE_RETRY = 6;
   protected static final int zRESPONSE_IGNORE = 7;

   public static final int zCALL_ERROR = -16;
   public static final int zMSGQ_OBJECT_CONSTRAINT_INFORMATION = 50;
   public static final int zMSGQ_OBJECT_CONSTRAINT_WARNING = 100;
   public static final int zMSGQ_DOMAIN_ERROR = 200;
   public static final int zMSGQ_OBJECT_CONSTRAINT_ERROR = 300;
   public static final int zMSGQ_REQUIRED_DATA_ITEM_ERROR = 400;
   public static final int zMSGQ_MODAL_ERROR = 500;
   public static final int zMSGQ_SYSTEM_ERROR = 1000;

   protected static final int zMSGQ_PROCESS_ACCEPT = 1;
   protected static final int zMSGQ_PROCESS_COMMIT = 2;
   protected static final int zMSGQ_PROCESS_DOMAIN = 3;

   protected static final int zCONSTRAINT_VIOLATION = -12;
   protected static final int zCALL_MIN_INFORC = -10;
   protected static final int zDB_UNAVAIL = -2;
   protected static final int zDB_DEADLOCK = -3;
   protected static final int zDUPLICATE_ROOT = -4;
   protected static final int zOPTIMISTIC_LOCK_ERROR = -5;
   protected static final int zLOCK_ERROR = -5;
   protected static final int zNETWORK_ERROR = -6;
   protected static final int zMEMORY_LIMIT = -7;

   protected static final int  zVAR_SET = 0;
   protected static final int  zVAR_NULL = -1; // Indicates that the attribute value is a null value
   protected static final int  zENTITY_NULL = -2;

   protected static final int zCOREMEM_ALLOC = 1;  // just to get things going
   protected static final int MB_OK = 1;  // just to get things going
   protected static final int REG_SZ = 1;  // just to get things going
   protected static final int REG_EXPAND_SZ = 2;  // just to get things going

   protected static final int zDT_YEAR   = 0;
   protected static final int zDT_MONTH  = 1;
   protected static final int zDT_DAY    = 2;
   protected static final int zDT_HOUR   = 3;
   protected static final int zDT_MINUTE = 4;
   protected static final int zDT_SECOND = 5;

   protected static final int qMAXRECEIVEISNEGATIVE = -2;
   protected static final int qMAXCOPYISNEGATIVE = -3;
   protected static final int qMAXRECEIVEEXCEEDSTARGETLEN = -4;
   protected static final int qINVALIDPARAMETER = -5;

   // defines for LPLR Types
   public static final int zREFER_HDR_META     = 2000;
   public static final int zREFER_SRC_META     = 2001;
   public static final int zREFER_GO_META      = 2002;
   public static final int zREFER_DOMAIN_META  = 2003;
   public static final int zREFER_ERD_META     = 2004;
   public static final int zREFER_SA_META      = 2005;
   public static final int zREFER_DTE_META     = 2006;
   public static final int zREFER_LOD_META     = 2007;
   public static final int zREFER_POD_META     = 2008;
   public static final int zREFER_VOR_META     = 2009;
   public static final int zREFER_PENV_META    = 2010;
   public static final int zREFER_DIALOG_META  = 2011;
   public static final int zREFER_UIS_META     = 2012;
   public static final int zREFER_DOMAINGRP_META = 2013;
   public static final int zREFER_GOPGRP_META  = 2014;
   public static final int zREFER_REPORT_META  = 2015;
   public static final int zREFER_XSLT_META    = 2016;
   public static final int zREFER_MAX_META     = 2016;

   public static final int zSOURCE_HDR_META     = 0;
   public static final int zSOURCE_SRC_META     = 1;
   public static final int zSOURCE_GO_META      = 2;
   public static final int zSOURCE_DOMAIN_META  = 3;
   public static final int zSOURCE_ERD_META     = 4;
   public static final int zSOURCE_SA_META      = 5;
   public static final int zSOURCE_DTE_META     = 6;
   public static final int zSOURCE_LOD_META     = 7;
   public static final int zSOURCE_POD_META     = 8;
   public static final int zSOURCE_VOR_META     = 9;
   public static final int zSOURCE_PENV_META    = 10;
   public static final int zSOURCE_DIALOG_META  = 11;
   public static final int zSOURCE_UIS_META     = 12;
   public static final int zSOURCE_DOMAINGRP_META = 13;
   public static final int zSOURCE_GOPGRP_META  = 14;
   public static final int zSOURCE_REPORT_META  = 15;
   public static final int zSOURCE_XSLT_META    = 16;
   public static final int zSOURCE_MAX_META     = 16;

   public static final int   zWAB_DeterminedInDialogOperation     = 0;
   public static final int   zWAB_StayOnWindow                    = 1;          // (PREVENT ACTION)
   public static final int   zWAB_StayOnWindowWithRefresh         = 2;
   public static final int   zWAB_StayOnWindowWebRefresh          = 3;

   public static final int   zWAB_StartOrFocusModelessDialog      = 30;
   public static final int   zWAB_StartDialogTask                 = 31;
   public static final int   zWAB_StartModelessWindow             = 32;
   public static final int   zWAB_StartOrFocusModelessWindow      = 38;
   public static final int   zWAB_StartModalWindow                = 36;
   public static final int   zWAB_StartModelessSubwindow          = 33;
   public static final int   zWAB_StartOrFocusModelessSubwindow   = 39;
   public static final int   zWAB_StartModalSubwindow             = 34;
   public static final int   zWAB_StartOrFocusModelessApp         = 37;
   public static final int   zWAB_StartNewApp                     = 35;

   public static final int   zWAB_ReplaceDialogWithDialog         = 51;
   public static final int   zWAB_ReplaceWindowWithModelessWindow = 52;
   public static final int   zWAB_ReplaceWindowWithModalWindow    = 53;
   public static final int   zWAB_ReplaceCurrentAppWithApp        = 54;

   public static final int   zWAB_SwitchToAction                  = -1;
   public static final int   zWAB_ReturnToParent                  = 71;
   public static final int   zWAB_ReturnToParentWithRefresh       = 72;
   public static final int   zWAB_ReturnToTopWindow               = 73;
   public static final int   zWAB_ReturnToTopWindowWithRefresh    = 74;
   public static final int   zWAB_StartTopWindow                  = 75;
   public static final int   zWAB_ResetTopWindow                  = 76;

   public static final int   zWAB_ExitDialogTask                  = 99;

   public static final int   zWAB_SuspendToDebugger               = 201;
   public static final int   zWAB_ResumeFromDebugger              = 202;

   public static final int   zWAB_TerminateActionForError         = 9999;
   public static final int   zWAB_ProcessImmediateAction          = 268435456;                         // 0x10000000L;
   public static final int   zWAB_NoDriverMessageOnError          = 536870912;                         // 0x20000000L;
   public static final int   zWAB_ProcessImmediateReturn          = 1073741824;                        // 0x40000000L;

   protected static final String[] g_Actions = {
           "DeterminedInDialogOperation", // 0
           "(1)StayOnWindow(NoRefresh)", // 1
           "(2)StayOnWindowWithRefresh", // 2

           "", "", "", "", "", "", "", "", "", "", // 3-12
           "", "", "", "", "", "", "", "", "", "", // 13-22
           "", "", "", "", "", "", "", // 23-29

           "(30)StartOrFocusModelessDialog", // 30
           "(31)StartDialogTask", // 31
           "(32)StartModelessWindow", // 32
           "(33)StartModelessSubwindow", // 33
           "(34)StartModalSubwindow", // 34
           "(35)StartNewApp", // 35
           "(36)StartModalWindow", // 36
           "(37)StartOrFocusModelessApp", // 37
           "(38)StartOrFocusModelessWindow", // 38
           "(39)StartOrFocusModelessSubwindow", // 39

           "(40)StartPopupMenu", // 40
           "(41)StartBrowserHTML_Page", // 41
           "(42)StartEmailClient", // 42
           "(43)StartEmailClientBCC", // 43
           "(44)StartEmailClientCC", // 44
           "(45)LinkToHTML_Address", // 45
           "(46)ProcessDownloadFile", // 46
           "(47)StartBrowserPDF_Page", //  47
           "", "", "", // 48-50

           "(51)ReplaceDialogWithDialog", // 51
           "(52)ReplaceWindowWithModelessWindow", // 52
           "(53)ReplaceWindowWithModalWindow", // 53
           "(54)ReplaceCurrentAppWithApp", // 54
           "(55)ReCAPTCHA Replace Window", // 55
           "", "", "", "", // 56-59

           "(60)PrintWindow", //  60
           "(61)StartSplitWindow", // 61
           "(62)ReplaceSplitWindow", // 62
           "(63)DeleteSplitWindow", // 63
           "", "", "", "", "", "", "", // 64-70

           "(71)ReturnToParent", // 71
           "(72)ReturnToParentWithRefresh", // 72
           "(73)ReturnToTopWindow", // 73
           "(74)ReturnToTopWindowWithRefresh", // 74
           "(75)StartTopWindow", // 75
           "(76)ReplaceTopWindow", // 76
           "", // 77
           "(78)StartModalWebPopup", // 78
           "(79)StartModelessWebPopup", // 79

           "", "", "", "", // 80-83
           "(84)ReturnFromWebPopupNoRefresh", // 84
           "(85)ReturnFromWebPopupWithRefresh", // 85

           "", "", "", "", "", // 86-90
           "", "", "", "", "", "", "", "", // 91-98

           "(99)ExitDialogTask", // 99
           "???", //  100
   };

   public static final String MSGQ_OBJECT_NAME = "__MSGQ";
   public static final String WEB_SESSION_VIEW_NAME = "_KZXMLPGO";
   public static final String MESSAGE_OBJECT_NAME = "KZMSGQOO";  // a version of this object exists in each LPLR

   //
   // Fields should not be initialized with anything but static values (preferably null).
   // VmlOperation will be instantiated many times and initialization must be cheap.
   //

   static final Map BaseMsgTable = ImmutableMap.builder()
      .put( 1, "KZOEE001 - Error communicating with client window" )
      .put( 2, "KZOEE002 - ZEIDON environment variable not set" )
      .put( 3, "KZOEE003 - Error starting Object Services" )
      .put( 4, "KZOEE004 - Error communicating with Object Services" )
      .put( 5, "KZOEE005 - Error communicating with Object Services" )
      .put( 6, "KZOEE006 - Internal error freeing Anchor Block" )
      .put( 7, "KZOEE007 - Internal Anchor block error, system restart recommended" )
      .put( 8, "KZOEE008 - Application definition file missing ZEIDON_BIN or ZEIDON_SYS" )
      .put( 9, "KZOEE009 - Error opening application definition file" )
      .put( 10, "KZOEE010 - Requested application not found" )
      .put( 11, "KZOEE011 - Error opening application domains file" )
      .put( 12, "KZOEE012 - Error allocating memory" )
      .put( 13, "KZOEE013 - Internal operation call error" )
      .put( 14, "KZOEE014 - Invalid suballoc memory free - ID=" )
      .put( 15, "KZOEE015 - Invalid suballoc memory free" )
      .put( 16, "KZOEE016 - Invalid Task" )
      .put( 17, "KZOEE017 - Task is Disabled" )
      .put( 18, "KZOEE018 - Error in Domain file, line: " )
      .put( 19, "KZOEE019 - Invalid GetTaskInfo request: " )
      .put( 20, "KZOEE020 - Invalid Operation call " )
      .put( 21, "KZOEE021 - Internal error, TaskOperation block has no Object/Entity/Attr" )
      .put( 22, "KZOEE022 - Error writing file" )
      .put( 23, "KZOEE023 - Invalid parameter, " )
      .put( 24, "KZOEE024 - Error opening file" )
      .put( 25, "KZOEE025 - Error in directory specification" )
      .put( 26, "KZOEE026 - Error creating directory" )

  // Errors in system services
      .put( 30, "KZOEE030 - Error loading library rc=" )
      .put( 31, "KZOEE031 - Error locating Operation rc=" )
      .put( 32, "KZOEE032 - Mutex name is invalid" )

  // beginning of application logic errors
  // Activate object errors
      .put( 50, "KZOEE050 - Error opening View Object file " )
      .put( 51, "KZOEE051 - Invalid View Object file header" )
      .put( 52, "KZOEE052 - Invalid Object file, Attrib w/o lth in defin prev to line " )
      .put( 53, "KZOEE053 - Invalid Entity level found on line " )
      .put( 54, "KZOEE054 - Invalid record found on line " )
      .put( 55, "KZOEE055 - Invalid file, LTH or TYPE before DOMAIN on line " )
      .put( 56, "KZOEE056 - Domain not found on line " )
      .put( 57, "KZOEE057 - Invalid file, LTH before type and DOMAIN on line " )
      .put( 58, "KZOEE058 - Invalid file, PERSIST after DOMAIN, TYPE or LTH on line " )
      .put( 59, "KZOEE059 - Invalid file, Invalid Attribute Token located on line " )
      .put( 60, "KZOEE060 - Invalid maximum root qualifier " )
      .put( 61, "KZOEE061 - Persistent Attribute mismatch on Token " )
      .put( 62, "KZOEE062 - Conflict between E/R Attribute Type and TE Field Type for: " )
      .put( 63, "KZOEE063 - Entity attrib RECURSIVE Y, but not structurally recursive " )
      .put( 64, "KZOEE064 - TYPE obsolete, use APDM_TOK " )
      .put( 65, "KZOEE065 - LTH only valid for Attribute w/type string line " )
      .put( 66, "KZOEE066 - Attribute length zero " )
      .put( 67, "KZOEE067 - Could not initialize the Core-MQ interface " )

  // Activate/Commit instance errors
      .put( 70, "KZOEE070 - Object instance is empty" )
      .put( 71, "KZOEE071 - Error opening instance file " )
      .put( 72, "KZOEE072 - Error reading instance file " )
      .put( 73, "KZOEE073 - Invalid instance file header" )
      .put( 74, "KZOEE074 - Invalid Entity name on line " )
      .put( 75, "KZOEE075 - Invalid Entity level on line " )
      .put( 76, "KZOEE076 - Object instance contains versioned entity instances" )
      .put( 77, "KZOEE077 - Invalid record size in binary object instance" )
      .put( 78, "KZOEE078 - Internal error, linked instance has no visible owner" )
      .put( 79, "KZOEE079 - Trying to commit a read-only view" )
      .put( 80, "KZOEE080 - Object Definition does not have a Database handler specified" )
      .put( 81, "KZOEE081 - Object Definition does not have a Genkey handler specified" )
      .put( 82, "KZOEE082 - Error starting Genkey handler" )
      .put( 83, "KZOEE083 - LOD does not have physical information.  Possibly the LOD was saved without DB information or the entities are work entities." )
      .put( 84, "KZOEE084 - Entity in Object Definition does not have Data Fields" )
      .put( 85, "KZOEE085 - Entity in Object Definition does not have Relationship Records" )
      .put( 86, "KZOEE086 - Trying to commit 0 views" )
      .put( 87, "KZOEE087 - Too many views in View array" )
      .put( 88, "KZOEE088 - Compressed OI is out of sync with LOD/XOD" )
   // .put( 89, "KZOEE089 - This error number may be re-used" )
      .put( 90, "KZOEE090 - Maximum number of entities in portable file exceeded: " )
      .put( 91, "KZOEE091 - Maximum number of entities in binary file exceeded" )
      .put( 92, "KZOEE092 - Couldn't re-activate OI for optimistic lock check" )
      .put( 93, "KZOEE093 - Optimistic locking error -- OI has changed since it was activated" )
      .put( 94, "KZOEE094 - Locking violation" )
      .put( 95, "KZOEE095 - A recursive child was found that matches a parent.  This will cause an infinite loop in the recursive subobject.  See Trace for more." )
      .put( 96, "KZOEE096 - Error retrieving OI from blob." )

  // View, entity, and attribute validation errors
      .put( 100, "KZOEE100 - Invalid View, view is a Subtask View" )
      .put( 101, "KZOEE101 - Invalid View" )
      .put( 102, "KZOEE102 - Invalid View, view is hidden" )
      .put( 103, "KZOEE103 - Invalid Entity name for View" )
      .put( 104, "KZOEE104 - Invalid Attribute name for LOD/Entity/Attribute" )
      .put( 105, "KZOEE105 - Invalid scoping Entity name for View" )
      .put( 106, "KZOEE106 - Rules violation " )
      .put( 107, "KZOEE107 - Invalid Subtask View" )
      .put( 108, "KZOEE108 - Attempt to drop Subtask View" )
      .put( 109, "KZOEE109 - Invalid View, view contains no instance" )
      .put( 110, "KZOEE110 - Invalid level for View name" )
      .put( 111, "KZOEE111 - Attempt to set subtask view with a view from another task" )
      .put( 112, "KZOEE112 - Attempt to set subtask view attached to an application" )
      .put( 113, "KZOEE113 - Invalid View, view contains an instance" )
      .put( 114, "KZOEE114 - Source and Target entities do not match" )
      .put( 115, "KZOEE115 - Attempt to move an instance under one of its children" )
      .put( 116, "KZOEE116 - Attempt to include an instance created under a versioned parent" )
      .put( 117, "KZOEE117 - Entity Instance Keys do not match" )
      .put( 118, "KZOEE118 - Internal Key error relinking versioned Subobject" )
      .put( 119, "KZOEE119 - Invalid View, View is Read Only" )
   // More at 450

  // Entity creation errors
      .put( 120, "KZOEE120 - Invalid position parameter" )
      .put( 121, "KZOEE121 - Attempt to insert twin to root of Instance" )
      .put( 122, "KZOEE122 - Attempt to create an Entity without a parent" )
      .put( 124, "KZOEE124 - Entity parent is included in another path containing same entity type" )
      .put( 125, "KZOEE125 - Target and Source Entities are not the same E/R Entity" )
      .put( 126, "KZOEE126 - Target or Source Entity is not Includeable" )
      .put( 127, "KZOEE127 - Source & target do not match on both Entity & Relationship." )
      .put( 128, "KZOEE128 - Target Entity cardinality max not 1 for inverted Subobject" )
      .put( 129, "KZOEE129 - Trying to create a relationship (via Include, possibly as part of a spawn ) that already exists.  See trace for more." )
      .put( 131, "KZOEE131 - Attempt to include Subobject from another Application Task" )
      .put( 132, "KZOEE132 - Error establishing cursor for Subobject include" )
      .put( 134, "KZOEE134 - Attempt to version an Entity Instance versioned via a differen, path" )
      .put( 135, "KZOEE135 - Entity Instance not versioned" )
      .put( 136, "KZOEE136 - Entity Instance already versioned" )
      .put( 137, "KZOEE137 - Entity Instance descendent versioned" )
      .put( 138, "KZOEE138 - Attempt to include target entity with recursive behavior" )
      .put( 139, "KZOEE139 - Error establishing cursor for CreateEntity spawn" )
      .put( 140, "KZOEE140 - Target and source Object instance are the same instance" )
      .put( 141, "KZOEE141 - Attempt to include a subobject whose root is a Temporal Entity" )

  // *More* view, entity, and attribute validation errors
      .put( 190, "KZOEE190 - Error opening temporary file" )
      .put( 191, "KZOEE191 - Attribute must be a Blob or String for this operation." )

  // Attribute processing errors
      .put( 231, "KZOEE231 - Decimal attribute overflow (garbage )" )
      .put( 232, "KZOEE232 - Operation indicates use default context, none found" )
      .put( 233, "KZOEE233 - Could not locate derived library/operation" )
      .put( 234, "KZOEE234 - Attempt to add integer or decimal to invalid attribute type" )
      .put( 235, "KZOEE235 - Integer overflow" )
      .put( 236, "KZOEE236 - Integer underflow" )
      .put( 237, "KZOEE237 - Attempt to update a non-updateable attribute" )
      .put( 238, "KZOEE238 - Attempt to update a non-updateable persistent attribute" )
      .put( 239, "KZOEE239 - Invalid Operation for attribute type" )
      .put( 240, "KZOEE240 - Binary large object (Blob ) exceeds passed length" )
      .put( 241, "KZOEE241 - Invalid Variable Type " )
      .put( 242, "KZOEE242 - Invalid Domain Entry Type" )
      .put( 243, "KZOEE243 - Context invalid for Domain" )
      .put( 244, "KZOEE244 - Attribute has no Domain" )
      .put( 245, "KZOEE245 - Null string not allowed for a required attribute" )
      .put( 246, "KZOEE246 - Invalid Attribute type " )
      .put( 247, "KZOEE247 - Blob Attribute does not match Target Entity Type" )
      .put( 248, "KZOEE248 - Required attribute is null" )

  // Cursor errors
      .put( 250, "KZOEE250 - Object instance is empty" )

      .put( 252, "KZOEE252 - Root of view has been deleted" )
      .put( 253, "KZOEE253 - Entity cursor is NULL" )
      .put( 254, "KZOEE254 - Entity cursor is undefined" )
      .put( 255, "KZOEE255 - Attempt to update a previous entity version" )
      .put( 256, "KZOEE256 - Entity is root of view" )
      .put( 257, "KZOEE257 - Version mismatch between scoping and target Entities" )
      .put( 258, "KZOEE258 - Scoping Entity cursor is undefined" )
      .put( 259, "KZOEE259 - Scoping Entity cursor is NULL" )
      .put( 263, "KZOEE263 - Input Qualifier cannot be converted to internal attribute data type" )
      .put( 264, "KZOEE264 - Invalid Operation for Hierarchical processing" )
      .put( 265, "KZOEE265 - Invalid Operation for non-Hierarchical processing" )
      .put( 266, "KZOEE266 - Invalid Operation for Hierarchical cursor position" )
      .put( 267, "KZOEE267 - Hierarchical cursor is undefined" )
      .put( 268, "KZOEE268 - Source and target entity types do not match" )
      .put( 269, "KZOEE269 - Invalid Select Set ID, ID=" )

  // View creation errors
      .put( 270, "KZOEE270 - View name is already in use" )
      .put( 271, "KZOEE271 - Subobject Entity is root of View Object Definition" )
      .put( 272, "KZOEE272 - Subobject Parent Cursor is NULL" )
      .put( 273, "KZOEE273 - Parent Entity instance for View deleted" )
      .put( 274, "KZOEE274 - Target and Source views are different View Object types" )

  // Meta Inquiry errors

      .put( 300, "KZOEE300 - Problems finding a parent " )
      .put( 301, "KZOEE301 - Return buffer not large enough to contain concatenated keys" )
      .put( 302, "KZOEE302 - Invalid option" )

  // Message Object errors

      .put( 330, "KZOEE330 - Message Object Definition not loaded for Application" )

  // Domain processing errors (Table Handler )
      .put( 350, "KZOEE350 - Context Not Valid for Domain" )
      .put( 351, "KZOEE351 - Invalid Input Data Type" )
      .put( 352, "KZOEE352 - Text String exceeds attribute length " )
      .put( 353, "KZOEE353 - Attribute Type invalid for this Domain" )
      .put( 354, "KZOEE354 - Invalid Domain Entry Type " )
      .put( 355, "KZOEE355 - Table_Handler invalid for this Domain Type " )
      .put( 356, "KZOEE356 - Domain has an unnamed Context " )
      .put( 357, "KZOEE357 - Invalid Input Data" )
      .put( 358, "KZOEE358 - Value not in Context for Domain " )
      .put( 359, "KZOEE359 - Invalid Input Data Type for Domain Entry Type" )
      .put( 360, "KZOEE360 - Missing ending delimiter " )
      .put( 361, "KZOEE361 - Invalid data Format " )
      .put( 362, "KZOEE362 - Variable Type not allowed for this Domain Type " )
      .put( 363, "KZOEE363 - Context Edit string is invalid " )
      .put( 364, "KZOEE364 - Picture length exceeds input length " )

  // Network Errors
      .put( 400, "KZOEE400 - Error transmitting OI -- some lines lost." )
      .put( 401, "KZOEE401 - Invalid User Name." )
      .put( 402, "KZOEE402 - Invalid Password." )
      .put( 403, "KZOEE403 - Application not supported by Security Object." )
      .put( 404, "KZOEE404 - Can't find UserGroup." )
      .put( 405, "KZOEE405 - UserGroup doesn't have authority for operation." )

      .put( 450, "KZOEE450 - Name for view is too long" )
      .put( 451, "KZOEE451 - Include source task does not match target task" )

      .put( 9999, "" )
      .build( );

/*
  // General Domain errors
  #if 0
  struct MsgTableStruct
   DomainMsgTable [] =
   {
     {1,"TZDME001 - Invalid Input Data Type"},
     {2,"TZDME002 - Text String exceeds attribute length "},
     {3,"TZDME003 - Attribute Type invalid for this Domain"},
     {4,"TZDME004 - Invalid Domain Entry Type "},
     {5,"TZDME005 - Table_Handler invalid for this Domain "},
     {6,"TZDME006 - Integer overflow"},
     {7,"TZDME007 - Integer underflow"},
     {8,"TZDME008 - Could not find context for Domain "},
     {9,"TZDME009 - Context edit string is invalid for Domain "},
    {10,"TZDME010 - DateTime input string invalid "},
    {11,"TZDME011 - Error storing value in record "},
    {12,"TZDME012 - Context Required when cType is zTYPE_INTEGER "},
    {13,"TZDME013 - Context/cType Combination is invalid "},
    {14,"TZDME014 - Context is for retrieval only "},
    {15,"TZDME015 - Context only used for arithmetic operations "},
    {16,"TZDME016 - Input invalid for context "},
    {17,"TZDME017 - Context Required when cType is zTYPE_DECIMAL "},
    {18,"TZDME018 - Context edit string is null "},
    {19,"TZDME019 - International number formatting is not available "},
    {20,"TZDME020 - Invalid decimal string "},
    {21,"TZDME021 - Return area not large enough for formatted string "},
    {22,"TZDME022 - AlphaNumeric and '_' are the only chars allowed "},
    {99,"TZDME099 - Forgot this one! "},
    {9999,""}
   };
  #endif
*/

   protected Task task;

   // Used by hierarchical cursors.
   private Iterator hierInstanceIterator;
   private String                             hierInstanceEntityName;

   /**
    * This attempts to find a task qualification object from a list of unknown objects.
    *
    * @param objects
    * @return
    */
   public static TaskQualification findTaskQual( Object...objects)
   {
       for ( Object o : objects )
       {
         if ( o instanceof TaskQualification )  // Null values return false.
         {
            return (TaskQualification) o;
         }
      }

      return null;
   }

   public VmlOperation( TaskQualification taskQual )
   {
      super( );
      if ( taskQual != null )
         setTaskQual( taskQual );
   }

   protected void setTaskQual( TaskQualification taskQual )
   {
      if ( taskQual != null )
         this.task = taskQual.getTask();
   }

   public static void SetZeidonSessionAttribute( HttpSession session, TaskQualification qual, String strCallingJSP, String strActionToProcess )
   {
      Task task = qual.getTask();
      if ( session != null )
      {
         session.setAttribute( "ZeidonAction", strActionToProcess ) ;
         task.log().info( "ZeidonAction ======> " + strCallingJSP + "." + strActionToProcess ); // remove for deployment?
      }
      else
      {
         task.log().info( "ZeidonOperation ======> " + strActionToProcess + " called from " + strCallingJSP ); // remove for deployment?
      }
   } // set breakpoint here

   // Returns the underlying view of zVIEW if view is an instance of zVIEW.
   // This is used in a few cases where we need to have the View instead of zVIEW.
   //
   // @param view
   // @return
   //
   private View getViewFromzVIEW( View view )
   {
      int count = 0;
      while ( view instanceof zVIEW )
      {
         if ( ++count == 1000 )
         {
            throw new ZeidonException( "Unreasonable number of nested zVIEWs" );
         }

         view = ((zVIEW) view).getView( );
      }

      return view;
   }

   protected static View getView( View v )
   {
      if ( v != null )
      {
         if ( v instanceof zVIEW )
         {
            v = ((zVIEW) v).getView( );
         }
      }

      return v;
   }

   public static boolean isValid( View v )
   {
       return getView( v ) != null;
   }

   public static void SfSetUserIdForTask( TaskQualification qual, String userId )
   {
      qual.getTask( ).setUserId( userId );
   }

   public static String SfGetUserIdForTask( TaskQualification qual )
   {
      return qual.getTask( ).getUserId( );
   }

   public static void SfGetUserIdForTask( TaskQualification qual, StringBuilder sbUserId )
   {
      sbUserId.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      sbUserId.append( qual.getTask( ).getUserId( ) );
   }

   protected void SfSetApplicationTask( TaskQualification qual, int i )
   {
      // TODO Auto-generated method stub
   }

   protected int SfGetApplicationForSubtask( StringBuilder sbApp, View view )
   {
      Application app = view.getApplication( );
      sbApp.setLength( 0 );
      sbApp.append( app.getName( ) );
      return sbApp.length( );
   }

   // TODO:  Do we need both of the following getMessageObject ops?  dks 2011.04.15
   private static View getMessageObject( TaskQualification taskQual )
   {
      View vMsgQ = taskQual.getViewByName( MSGQ_OBJECT_NAME );
      if ( vMsgQ == null )
      {
         vMsgQ = taskQual.activateEmptyObjectInstance( MESSAGE_OBJECT_NAME );
         vMsgQ.cursor( "Task" ).createEntity().getAttribute( "Id" ).setValue( taskQual.getTask().getTaskId() );
         vMsgQ.setName( MSGQ_OBJECT_NAME );
      }

      return vMsgQ;
   }

   public static View getMessageObject( Task task )
   {
      View vMsgQ = task.getViewByName( MSGQ_OBJECT_NAME );
      if ( vMsgQ == null )
      {
         vMsgQ = task.activateEmptyObjectInstance( MESSAGE_OBJECT_NAME );
         vMsgQ.cursor( "Task" ).createEntity().getAttribute( "Id" ).setValue( task.getTask().getTaskId() );
         vMsgQ.setName( MSGQ_OBJECT_NAME );
      }

      return vMsgQ;
   }

   /**
    * Resets the message object.
    *
    * @param taskQual
    */
   public static void resetMessageObject( TaskQualification taskQual )
   {
      View vMsgQ = taskQual.getViewByName( MSGQ_OBJECT_NAME );
      if ( vMsgQ != null )
      {
         vMsgQ.drop();
      }
   }

   public static void resetMessageObject( Task task )
   {
      View vMsgQ = task.getViewByName( MSGQ_OBJECT_NAME );
      if ( vMsgQ != null )
      {
         vMsgQ.drop();
      }
   }

   /**
    * Looks for the message object and if it finds one throws an ObjectConstraintException.
    * Called from the JOE to support legacy VML applications.
    *
    * @param task
    * @param rc
    */
   public static void throwMessageObject( View view, int rc ) throws ObjectConstraintException
   {
      View vMsgQ = getMessageObject( view.getTask( ) );
      StringBuilder sb = new StringBuilder();
      for ( EntityInstance ei : vMsgQ.cursor( "WebMsg" ).eachEntity() )
      {
         sb.append( ei.getAttribute( "ErrorMsg" ).getString() );
         sb.append( "\n" );
      }

      throw new ObjectConstraintException( view, rc, sb.toString() );
   }

   /**
    * Adds a message to the message object for the current task.
    *
    * @param taskQual
    * @param msgId
    * @param msgTitle
    * @param msgText
    * @param msgType
    * @param beep
    */
   public static final int  MessageSend( TaskQualification taskQual,
                                         String            msgId,
                                         String            msgTitle,
                                         String            msgText,
                                         int               msgType,
                                         int               beep )
   {
      View vMsgQ = getMessageObject( taskQual );
      vMsgQ.cursor( "WebMsg" ).createEntity()
                              .getAttribute( "Id" ).setValue( msgId )
                              .getAttribute( "Title").setValue( msgTitle )
                              .getAttribute( "ErrorMsg").setValue( msgText )
                              .getAttribute( "Type").setValue( msgType )
                              .getAttribute( "Beep").setValue( beep );
      return 0;
   }

   public static final int MessageSend( View view, String msgId, String msgTitle, StringBuilder sbMsgText, int msgType, int beep )
   {
      return MessageSend( view, msgId, msgTitle, sbMsgText.toString( ), msgType, beep );
   }

   public static final int MessageSend( View view, int msgId, String msgTitle, String msgText, int msgType, int beep )
   {
      return MessageSend( view, "", msgTitle, msgText, msgType, beep );
   }

   public static final int MessagePrompt( View view, String msgId, String msgTitle, String msgText,
                                          int beep, int buttons, int defaultButton, int icon )
   {
      return MessageSend( view, msgId, msgTitle, msgText, 0, beep );
   }

   public static final int MessagePrompt( View view, int msgId, String msgTitle, String msgText,
                                          int beep, int buttons, int defaultButton, int icon )
   {
      return MessageSend( view, "", msgTitle, msgText, 0, beep );
   }

   public static final int MessagePromptForInput( View view, String msgTitle, String msgText,
                                                  String string3, int beep, StringBuilder sbPasswordEntered, int j )
   {
      // TODO Not doing the right thing!!!
      return MessageSend( view, "", msgTitle, msgText, 0, beep );
   }

   /**
    * This is public so it can be called from non-generated code if necessary.
    *
    * @param view
    * @param msgTitle
    * @param msgText
    * @param beep
    */
   public static final void SysMessageBox( View view, String msgTitle, String msgText, int beep )
   {
      String inServer = "";
      if ( isValid( view ) ) {
         inServer = view.readZeidonConfig( view.getApplication().getName(), "InServer" );
      }
      if ( inServer != null && inServer.equals( "Y" ) ) {
         view.log( ).info( msgTitle + " " + msgText );
      } else {
         JoeUtils.sysMessageBox( msgTitle, msgText );
      }
   }

   public static final void SysMessageBox( String msgTitle, String msgText )
   {
      SysMessageBox( null, msgTitle, msgText, 0 );
   }

   protected static final int OperatorPrompt( View view, String msgTitle, String msgText, int beep, int buttons, int defaultButton, int icon )
   {
      // TODO finish up
      return MessageSend( view, "", msgTitle, msgText, 0, beep );
   }

   protected static final int OperatorPromptForInput( View view, String msgTitle, String msgText, int buttons, StringBuilder sbReturnString, int icon )
   {
      // TODO this does not do what is required!!!
      return MessageSend( view, "", msgTitle, msgText, 0, 0 );
   }

   protected static final int OperatorPromptForFile( View view, StringBuilder sbFileName, int i, String string, String string2, int j )
   {
      // TODO ... DKS???
      return 0;
   }

   /////////////////////////////////////////////////////////////////////////////
   //
   //  ENTRY:      SysGetBaseMessage
   //
   // PROTOTYPE:
   //
   //     int  OPERATION
   //     SysGetBaseMessage( zPCHAR pchReturnString, long lMessageID, int nMaxLth )
   //
   // PURPOSE:  To return a base object engine message from the base
   //           message table.
   //
   // RETURNS: The length of the message returned
   //
   /////////////////////////////////////////////////////////////////////////////
   private int SysGetBaseMessage( StringBuilder sbReturnString, int lID, int nMaxLth )
   {
      sbReturnString.setLength( 0 );
      sbReturnString.append( BaseMsgTable.get( lID ) );
      if ( sbReturnString.length() > nMaxLth )
      {
         sbReturnString.setLength( nMaxLth );
      }

      return sbReturnString.length();
   }

   protected static final void IssueError( View view, int nSeverity, int nID, String stringMsg )
   {
      SysMessageBox( view, nSeverity < 16 ? "Application Logic Error" : "OE System Error", stringMsg, 0 );
   }

   protected static final void IssueError( View view, int nSeverity, double d, String stringMsg )
   {
      SysMessageBox( view, nSeverity < 16 ? "Application Logic Error" : "OE System Error", stringMsg, 0 );
   }

   public static final void IssueError( View view, String stringMsg )
   {
      SysMessageBox( view, "Logic Error", stringMsg, 0 );
   }

   //./ ADD NAME=IssueError
   // Source Module=kzoeeraa.c
   /////////////////////////////////////////////////////////////////////////////
   //
   //  ENTRY:      IssueError
   //
   //  PURPOSE:    To log an error situation
   //
   //  DESCRIPTION: Object Services, clients, and system software can
   //               call this operation to raise an error situation at
   //               any time during processing.
   //
   //               Severity: 16 - catastrophic error      (Object services)
   //                         12 - Application logic error (Object services)
   //                          8 - Application logic error (Application)
   //                          4 - Domain errors           (Application)
   //                          0 - Information logging msg
   //
   /////////////////////////////////////////////////////////////////////////////
   public int
   IssueError( zVIEW       lpView,
               int         nSeverity,
               int         nID,
               String      cpcMessage )
   {
      String    szTitle;

      if ( nSeverity < 16 )
      {
         szTitle = "Object Services - Application Logic Error";
      }
      else
      {
         szTitle = "OE System Error";
      }

      // Log the error with the subtask
      // TEMP For now, we just spit all errors out to the window!!! TEMP
      TraceLineS( "IssueError: ", cpcMessage );
      SysMessageBox( lpView, szTitle, cpcMessage, 1 );         // TEMP

      return 0;   // Error creating error object
   }

   //./ ADD NAME=fnIssueCoreError
   /////////////////////////////////////////////////////////////////////////////
   //
   //  FUNCTION:    fnIssueCoreError
   //
   /////////////////////////////////////////////////////////////////////////////
   public int
   fnIssueCoreError( TaskQualification task,
                     View         view,
                     int          nSeverity,
                     int          nID,
                     int          lLong,         // Additional info
                     String       cpcMessage1,   // Additional info
                     String       cpcMessage2 )  // Additional info
   {
      synchronized( lockMessage )
      {
         return IssueOE_Error( task, nSeverity, nID, zMSGQ_SYSTEM_ERROR,
                               lLong, cpcMessage1, cpcMessage2 );
      }
   }

   //./ ADD NAME=IssueOE_Error
   /////////////////////////////////////////////////////////////////////////////
   //
   //  FUNCTION:    IssueOE_Error
   //
   //  nSeverity    4 - Data Validation Error
   //               8 - Application Logic Error
   //              16 - OE System Error
   //              20 - Catastrophic Error (straight to SysMessageBox)
   //
   /////////////////////////////////////////////////////////////////////////////
   private int
   IssueOE_Error( TaskQualification  taskQual,
                  int         nSeverity,
                  int         nID,
                  int         lMsgType,
                  int         lLong,          // additional info
                  String      cpcMessage1,    // additional info
                  String      cpcMessage2 )   // additional info
   {
      Task      task;
      StringBuilder sbCoreMessage = new StringBuilder();
      String    cpcMsgId;
      zVIEW     zView = new zVIEW();
      String    pchTitle;
      LodDef    lpLodDef;

      task = taskQual.getTask();
      if ( task.isValid() )
      {
         for ( View v : task.getViewList() )
         {
            if ( isValid( v ) )
            {
               zView.setView( v );
               break;
            }
         }
      }

      // If the view is valid we'll pass it along, otherwise we will pass
      // the first SubtaskView for the task.
      if ( isValid( zView ) == false )
      {
         task = null;
         zView = null;
         lpLodDef = null;
      }

      SysGetBaseMessage( sbCoreMessage, nID, 256 );
      if ( sbCoreMessage.length() == 0 )
      {
         zstrcpy( sbCoreMessage, "Unknown Error Message (" );
         sbCoreMessage.append( zltoa( nID ) );
         zstrcat( sbCoreMessage, ") " );
      }

      if ( lLong != 0 )
      {
         sbCoreMessage.append( zltoa( lLong ) );
      }

      if ( cpcMessage1.isEmpty() == false )  // if any additional information
      {
         zstrcat( sbCoreMessage, ",\n\n " );
         zstrcat( sbCoreMessage, cpcMessage1 );
         if ( cpcMessage2.isEmpty() == false )
         {
            zstrcat( sbCoreMessage, ",\n" );
            zstrcat( sbCoreMessage, cpcMessage2 );
         }
      }

      TraceLineS( "IssueOE_Error : ", sbCoreMessage.toString() );

      // See if we can determine the view object resulting in the error.
      // But don't do it for EE071 or EE101 as it implies erroneous information.
      if ( isValid( zView ) && zView.getLodDef() != null && nID != 71 && nID != 101 )  // dks 2006.04.27
      {
          zstrcat( sbCoreMessage, ",\n\nView Object: " );
          zstrcat( sbCoreMessage, zView.getLodDef().getName() );
      }

      /**********
      // See if we can determine the operation.
      if ( lpTask != null && lpTask->bAudit && lpTask->nOperIdx > -1 )
      {
         String szOperationName[ 32 ];

         szOperationName[ 0 ] = 0;
         SysGetOperationMessage( szOperationName,
                              // lpTask->nOper[ 0 ], 31 );
                                 lpTask->nOper[ lpTask->nOperIdx ], 31 );
         if ( szOperationName[ 0 ] == 0 )
         {
            szOperationName[ 0 ] = '(';
         // zltoa( lpTask->nOper[ 0 ], &szOperationName[ 1 ] );
            zltoa( lpTask->nOper[ lpTask->nOperIdx ], &szOperationName[ 1 ] );
            zstrcat( szOperationName, ")" );
         }

         zstrcat( sbCoreMessage, ",\nOperation: " );
         zstrcat( sbCoreMessage, szOperationName );
         if ( lpTask->nOperIdx > 0 )
         {
            for ( int k = lpTask->nOperIdx - 1; k > -1 ; k-- )
            {
               zstrcat( sbCoreMessage, ", " );
               szOperationName[ 0 ] = 0;
               SysGetOperationMessage( szOperationName, lpTask->nOper[ k ], 31 );
               if ( szOperationName[ 0 ] == 0 )
               {
                  szOperationName[ 0 ] = '(';
                  zltoa( lpTask->nOper[ k ], &szOperationName[ 1 ] );
                  zstrcat( szOperationName, ") " );
               }

               zstrcat( sbCoreMessage, szOperationName );
            }
         }
      }
      */

      TraceLine( "IssueOE_Error:  %s  Severity: %d", sbCoreMessage, nSeverity );

      if ( nSeverity > 16 )
      {
         return IssueError( zView, nSeverity, nID, sbCoreMessage.toString() );
      }

/* #ifndef __DO_MSGOBJ__
      if ( lpTask == 0 )
         return( IssueError( zView, nSeverity, nID, szCoreMessage ) );
   #endif
*/
      if ( nSeverity == 16 )
      {
         pchTitle = "OE System Error";
      }
      else
      {
         pchTitle = "Object Services - Application Logic Error";
      }

      cpcMsgId = zltoa( nID ); // convert message id to a string
      return MessageSend( zView, cpcMsgId, "Object Services - Application Logic Error", sbCoreMessage,
                          lMsgType + nSeverity, 0 );
   }

   public static void CreateMessage( Task task, String controlTag, String errorReason, String mapValue )
   {
      // Create an entity in the message queue object.
      View vMsgQ = VmlOperation.getMessageObject( task );  // message queue
      vMsgQ.cursor( "WebMsg" ).createEntity( CursorPosition.NEXT );
      vMsgQ.cursor( "WebMsg" ).getAttribute( "ControlTag" ).setValue( controlTag );
      if ( errorReason.equals( "Invalid table domain value." ) )
      {
         errorReason = "The value '" + mapValue + "' is invalid.";
      }
      // The whole message wasn't being displayed in the jsp code if double quotes exist in the
      // error message. Take double quotes out.
      errorReason = errorReason.replace("\"", "\'");

      vMsgQ.cursor( "WebMsg" ).getAttribute( "ErrorMsg" ).setValue( errorReason );
      vMsgQ.cursor( "WebMsg" ).getAttribute( "ErrorMapValue" ).setValue( mapValue );
   }

   public static void ReplaceMessage( Task task, String controlTag, String errorReason, String mapValue, boolean evenWithError )
   {
      // Create an entity in the message queue object.
      View vMsgQ = VmlOperation.getMessageObject( task );  // message queue

      vMsgQ = vMsgQ.newView( );

      if ( vMsgQ.cursor( "Task" ).setFirst( "Id", task.getTask( ).getTaskId( ) ).isSet() &&
           vMsgQ.cursor( "WebMsg" ).setFirst( "ControlTag", controlTag ).isSet() )
      {
         String s = vMsgQ.cursor( "WebMsg" ).getAttribute( "ErrorMsg" ).toString();
         if ( s == null || s.isEmpty( ) || evenWithError )
         {
            vMsgQ.cursor( "WebMsg" ).getAttribute( "ErrorMsg" ).setValue( errorReason );
            vMsgQ.cursor( "WebMsg" ).getAttribute( "ErrorMapValue" ).setValue( mapValue );
         }
      }
      else
      {
         CreateMessage( task, controlTag, errorReason, mapValue );
      }
   }

   protected static final int ZeidonStringFind( StringBuilder sbTarget, int tgtIdx, String searchString )
   {
      return sbTarget.toString( ).lastIndexOf( searchString, tgtIdx - 1 );
   }

   protected static final int ZeidonStringFind( String tgtString, int tgtIdx, String searchString )
   {
      return tgtString.lastIndexOf( searchString, tgtIdx - 1 );
   }

   protected int SetNameForView( View view, String name, TaskQualification taskQual, int level )
   {
      Task t;
      Application a;
      View v;
      boolean autodrop;

      view = VmlOperation.getView( view );
      if ( taskQual instanceof zVIEW || taskQual instanceof View )
      {
         v = VmlOperation.getView( (View) taskQual );
         a = v.getApplication();
         t = v.getTask();
      }
      else
      {
         if ( taskQual == null )
         {
            v = view;
            a = v.getApplication();
            t = v.getTask();
         }
         else
         {
            v = null;
            a = taskQual.getApplication();
            t = taskQual.getTask();
         }
      }

      if ( (level & zNAME_AUTODROP) != 0 )
      {
         autodrop = true;
         level &= ~zNAME_AUTODROP;
      }
      else
      {
         autodrop = false;
      }

      switch ( level )
      {
         case zLEVEL_SUBTASK:
            if ( isValid( v ) == false )
            {
            // v = view;
               throw new ZeidonException( "Qualification view required for SetNameForView at the subtask level" );
            }

            if ( DriverApplication.isValidSubtaskView( v ) )
            {
            // TraceLine( "SetNameForView (%d) Subtask (%d) level for Name: %s  Task: %s", view.getId(), v.getId(), name, t.getTaskId() );
               v.setNameForSubtask( name, view );
               break;
            }

            TraceLine( "SetNameForView (%d) Invalid Subtask (%d) view for Name: %s  Task: %s", view.getId(), v.getId(), name, t.getTaskId() );
            throw new ZeidonException( "Invalid subtask used in SetNameForView: %s", name );

         case zLEVEL_TASK:
         // TraceLine( "SetNameForView (%d) Task level for Name: %s  Task: %s", view.getId(), name, t.getTaskId() );
            t.setNameForView( name, view );
            break;

         case zLEVEL_APPLICATION:
         // TraceLine( "SetNameForView (%d) Application (%s) level for Name: %s  Task: %s", view.getId(), a.getName(), name, t.getTaskId() );
            a.setNameForView( name, view );
            break;

         case zLEVEL_SYSTEM:
         // TraceLine( "SetNameForView (%d) System level for Name: %s  Task: %s", view.getId(), name, t.getSystemTask().getTaskId() );
            t.getSystemTask().setNameForView( name, view );
            break;

         default:
            throw new ZeidonException( "Invalid flag used in SetNameForView: %d", level );
      }

      return 0;
   }

   /**
    * This is defined so we can handle the (majority of) cases where the viewQual is generated as a 0.
    */
   protected int SetNameForView( View view, String name, int viewQual, int level )
   {
      return SetNameForView( view, name, null, level );
   }

   public int GetViewByName( zVIEW returnView, String name, TaskQualification taskQual, int level )
   {
      Task t;
      Application a;
      View v;

      // The view for KZXMPGO is named _KZXMLPGO.
      if ( name.equals( "KZXMLPGO") )
      {
         name = "_KZXMLPGO";
      }

      returnView.setView( null );  // initialize return view to null

      if ( taskQual == null )
      {
         throw new ZeidonException( "TaskQualification required for GetViewByName" );
      }
      else
      {
         if ( taskQual instanceof zVIEW || taskQual instanceof View )
         {
            v = VmlOperation.getView( (View) taskQual );
            a = v.getApplication();
            t = v.getTask();
         }
         else
         {
            v = null;
            a = taskQual.getApplication();
            t = taskQual.getTask();
         }
      }

      do  // purist's goto
      {
         // Check for valid name and scope.
         if ( name.length() == 0 )
         {
            throw new ZeidonException( "Empty name used in GetViewByName: %s", name );
         }

         if ( (level == zLEVEL_SUBTASK || level == zLEVEL_TASK ||
               level == zLEVEL_APPLICATION || level == zLEVEL_SYSTEM || level == zLEVEL_ANY) )
         {
            // If user wants a subtask view make sure subtask is OK.
            if ( level == zLEVEL_SUBTASK || level == zLEVEL_ANY  )
            {
               if ( DriverApplication.isValidSubtaskView( v ) )
               {
                  returnView.setView( v.getViewByNameForSubtask( name ) );
               }
               else
               if ( level == zLEVEL_SUBTASK )
               {
                  TraceLine( "GetViewByName Invalid Subtask view: %d  for Name: %s  Task: %s", v.getId(), name, t.getTaskId() );
                  throw new ZeidonException( "Invalid subtask used in GetViewByName: %s", name );
               }

               if ( isValid( returnView ) )
               {
               // TraceLine( "GetViewByName located Subtask level view: %d  for Name: %s  Task: %s", v.getId(), name, t.getTaskId() );
                  return zLEVEL_SUBTASK;
               }

               if ( level == zLEVEL_SUBTASK )
               {
                  TraceLine( "GetViewByName did not locate Subtask level view: %d  for Name: %s  Task: %s", v.getId(), name, t.getTaskId() );
                  return -1;  // view invalid
               }
            }

            if ( level == zLEVEL_TASK || level == zLEVEL_ANY )
            {
               returnView.setView( t.getViewByName( name ) );
               if ( isValid( returnView ) )
               {
                 if ( v == null )
                  {
                  // TraceLine( "GetViewByName located Task level view for Name: %s  Task: %s", name, t.getTaskId() );
                  }
                  else
                  {
                  // TraceLine( "GetViewByName located Task level view: %d  for Name: %s  Task: %s", v.getId(), name, t.getTaskId() );
                  }

                  return zLEVEL_TASK;
               }

               if ( level == zLEVEL_TASK )
               {
                  if ( v == null )
                  {
                     TraceLine( "GetViewByName did not locate Task level view for Name: %s  Task: %s", name, t.getTaskId() );
                  }
                  else
                  {
                     TraceLine( "GetViewByName did not locate Task level view: %d  for Name: %s  Task: %s", v.getId(), name, t.getTaskId() );
                  }

                  return -1;  // view invalid
               }
            }

            if ( level == zLEVEL_APPLICATION || level == zLEVEL_ANY )
            {
               returnView.setView( a.getViewByName( name ) );
               if ( isValid( returnView ) )
               {
                  if ( v == null )
                  {
                  // TraceLine( "GetViewByName located Application (%s) level view for Name: %s  Task: %s", a.getName(), name, t.getTaskId() );
                  }
                  else
                  {
                  // TraceLine( "GetViewByName located Application (%s) level view: %s  for Name: %s  Task: %s", a.getName(), v.getId(), name, t.getTaskId() );
                  }

                  return zLEVEL_APPLICATION;
               }

               if ( level == zLEVEL_APPLICATION )
               {
                  if ( v == null )
                  {
                     TraceLine( "GetViewByName did not locate Application (%s) level view for Name: %s  Task: %s", a.getName(), name, t.getTaskId() );
                  }
                  else
                  {
                     TraceLine( "GetViewByName did not locate Application (%s) level view: %s  for Name: %s  Task: %s", a.getName(), v.getId(), name, t.getTaskId() );
                  }

                  return -1;  // view invalid
               }
            }

            // It has to be SYSTEM or ANY level.
            t = t.getSystemTask();
            returnView.setView( t.getViewByName( name ) );
            if ( isValid( returnView ) )
            {
               if ( v == null )
               {
               // TraceLine( "GetViewByName located System level view for Name: %s  Task: %s", name, t.getTaskId() );
               }
               else
               {
               // TraceLine( "GetViewByName located System level view: %d  for Name: %s  Task: %s", v.getId(), name, t.getTaskId() );
               }

               return zLEVEL_SYSTEM;
            }

            if ( level == zLEVEL_SYSTEM )
            {
               if ( v == null )
               {
                  TraceLine( "GetViewByName did not locate System level view for Name: %s  Task: %s", name, t.getTaskId() );
               }
               else
               {
                  TraceLine( "GetViewByName did not locate System level view: %d  for Name: %s  Task: %s", v.getId(), name, t.getTaskId() );
               }

               return -1;  // view invalid
            }
         }
         else
         {
            throw new ZeidonException( "Invalid level used in GetViewByName: %d", level );
         }
      } while ( false );

      if ( v == null )
      {
         TraceLine( "GetViewByName did not locate ANY level view for Name: %s  Task: %s", name, t.getTaskId() );
      }
      else
      {
         TraceLine( "GetViewByName did not locate ANY level view: %d  for Name: %s  Task: %s", v.getId(), name, t.getTaskId() );
      }

      return -1;  // view invalid
   }

/*
   protected int GetViewByName( zVIEW returnView, String name, View qual, int level )
   {
      View view = null;
      int  nRC;

      // The view for KZXMPGO is named _KZXMLPGO.
      if ( name.equals( "KZXMLPGO") )
      {
         name = "_KZXMLPGO";
      }

      // Check for valid scope.
      if ( name.isEmpty() == false &&
           (level == zLEVEL_SUBTASK || level == zLEVEL_TASK || level == zLEVEL_APPLICATION ||
            level == zLEVEL_SYSTEM || level == zLEVEL_ANY) )
      {
      switch ( level )
      {
         case zLEVEL_ALL:
         case zLEVEL_SUBTASK:
            nRC = zLEVEL_SUBTASK;
            view = ((View) qual).getViewByNameForSubtask( name );
            if ( view != null || level == zLEVEL_SUBTASK )
            {
               break;
            }

            // Fall through for zLEVEL_ALL...

         case zLEVEL_TASK:
            nRC = zLEVEL_TASK;
            view = qual.getViewByName( name );
            if ( view != null || level == zLEVEL_TASK )
            {
               break;
            }

            // Fall through for zLEVEL_ALL...

         case zLEVEL_APPLICATION:
            nRC = zLEVEL_APPLICATION;
            view = qual.getViewByName( name );
            if ( view != null || level == zLEVEL_APPLICATION )
            {
               break;
            }

            // Fall through for zLEVEL_ALL...

         case zLEVEL_SYSTEM:
            nRC = zLEVEL_SYSTEM;
            view = qual.getSystemTask().getViewByName( name );
            if ( view != null )
            {
               break;
            }

         default:
            throw new ZeidonException( "Invalid flag used in GetViewByName: %d", level);
      }
      }

      if ( view == null )
      {
         nRC = -1;
      }
   // else
   // {
   //    TraceLineS( "GetViewByName: ", name );
   //    DisplayObjectInstance( view, "", "" );
   // }

      returnView.setView( view );
      return nRC;
   }
*/

   protected int DropNameForView( View view, String name, View viewQual, int level )
   {
      switch ( level )
      {
         case zLEVEL_SUBTASK:
            viewQual.dropNameForSubtask( name, view );
            break;

         case zLEVEL_TASK:
            view.dropNameForView( name );
            break;

         case zLEVEL_APPLICATION:
            Application app = viewQual.getApplication( );
            app.dropNameForView( name, view );
            break;

         case zLEVEL_SYSTEM:
            viewQual.getSystemTask().dropNameForView( name, view );
            break;

         default:
            throw new ZeidonException( "Invalid flag used in DropNameForView: %d", level );
      }

      return 0;
   }

   protected int DropNameForView( View view, String name, int viewQual, int level )
   {
      return DropNameForView( view, name, null, level );
   }

   protected int CreateViewFromView( zVIEW tgtView, View srcView )
   {
      srcView = getViewFromzVIEW( srcView );
      View newView = srcView.newView( );
      newView.copyCursors( srcView );
      tgtView.setView( newView );
      return 0;
   }

   protected int CreateViewFromViewForTask( zVIEW tgtView, View srcView, View vTask )
   {
      srcView = getViewFromzVIEW( srcView );
      View newView = srcView.activateOiFromOi( ACTIVATE_CONTROL.get( 0 ) );
      newView.copyCursors( srcView );
      tgtView.setView( newView );
      tgtView.setTaskQual( vTask );
      return 0;
   }

   protected int SetViewFromView( View tgtView, View srcView )
   {
      tgtView.copyCursors( getViewFromzVIEW( srcView ) );
      return 0;
   }

   protected int SetViewFromView( zVIEW tgtView, View srcView )
   {
      if ( tgtView.getView() == null )
      {
         View newView = srcView.newView( );
         tgtView.setView( newView );
      }

      tgtView.copyCursors( getViewFromzVIEW( srcView ) );
      return 0;
   }

   // RETURNS: 0           - View successfully set for subobject
   //          1           - View is currently established on the subobject
   //          zCALL_ERROR - error creating new view
   protected int SetViewToSubobject( View view, String entityName )
   {
      LodDef lodDef = view.getLodDef();
      EntityDef entityDef = lodDef.getEntityDef( entityName );

      // The C OE doesn't mind the user trying to set the subobject for non-recursive
      // entities but the JOE will throw an exception. To emulate the C OE we'll ignore
      // non recursive entities.
      // TODO: some day we need to restrict the OI to the subobject.
      if ( ! entityDef.isRecursive() )
          return 0;

      EntityCursor cursor = view.cursor( entityName );
      cursor.setToSubobject();
      return 0;
   }

   //  RETURNS: 0           - View successfully reset
   //           1           - View is not currently on a subobject
   //           zCALL_ERROR - error creating new view
   protected int ResetViewFromSubobject( View view )
   {
      int nRC = 0;
      if ( isValid( view ) == false )
      {
         nRC = zCALL_ERROR;
      }
      else
      {
         view.resetSubobject();
      }

      return nRC;
   }

   protected int ResetViewFromSubobjectTop( View view )
   {
      int nRC = 0;
      if ( isValid( view ) == false )
      {
         nRC = zCALL_ERROR;
      }
      else
      {
         view.resetSubobjectTop();
      }

      return nRC;
   }

   protected int MoveSubobject( View tgtView, String tgtEntityName,
                                View srcView, String srcEntityName, int pos, int repos )
   {
      EntityCursor tgtCursor = tgtView.cursor( tgtEntityName );
      EntityCursor srcCursor = srcView.cursor( srcEntityName );
      int  nRC = tgtCursor.moveSubobject( CURSOR_POS.get( pos ), srcCursor, CURSOR_POS.get( repos ) ).toInt();

      return nRC;
   }

   /**
    * Concatenates two strings and returns the results.
    * Intended to be used in code created by the VML generator.
    * @param s1 - Source string
    * @param s2 -
    * @return
    */
   protected static final String zstrcat( String s1, Object... arr )
   {
      return zstrcat( new StringBuilder( s1 ), arr ).toString( );
   }

   /**
    * Appends a string to a StringBuilder and returns the results.
    * Intended to be used in coded created by the VML generator.
    * @param s1 - Source string builder
    * @param s2 -
    * @return
    */
   protected static final StringBuilder zstrcat( StringBuilder sb, Object... arr )
   {
      for ( Object o : arr )
      {
         sb.append( o );
      }

      return sb;
   }

   protected String zsprintf( String tgtString, String strFormat, Object... arr )
   {
      tgtString = String.format( strFormat, arr );
      return tgtString;
   }

   protected void zsprintf( StringBuilder sbTgt, String strFormat, Object... arr )
   {
      sbTgt.setLength( 0 );
      sbTgt.append( String.format( strFormat, arr ) );
   }

   protected static final int zstrcpy( StringBuilder sb, Object s2, Object... arr )
   {
      sb.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      sb.append( s2.toString( ) );

      for ( Object o : arr )
      {
         sb.append( o );
      }

      return sb.length( );
   }

   protected static final String zstrcpy( String s, Object s2, Object... arr )
   {
      StringBuilder sb = new StringBuilder( s2.toString( ) );
      for ( Object o : arr )
      {
         sb.append( o );
      }

      return sb.toString( );
   }

   protected static final int zstrcpy( CharBuffer charBuffer, int nOffset, String s )
   {
      int k;

      for ( k = 0; k < s.length( ); k++ )
      {
         charBuffer.put( nOffset++, s.charAt( k ) );
      }

      return nOffset;  // current used length of charBuffer
   }

   protected static final int zstrcpy( StringBuilder sb, int nOffset, String s )
   {
      if ( nOffset < sb.length() )
      {
         sb.setLength( nOffset );
      }
      if ( s != null )  // insert unfortunately appends the string "null" if inserting a null string
      {
         sb.insert( nOffset, s );
      }

      return sb.length( );
   }

   protected static final int zstrncpy( StringBuilder sb, String s2, int nLth )
   {
      sb.setLength( 0 );
      if ( s2.length() < nLth )
      {
         nLth = s2.length();
      }

      sb.append( s2.substring( 0, nLth ) );
      return sb.length( );
   }

   protected static final  String zstrncpyoffset( String s, String s2, int nLth, int nOffset )
   {
      if ( s2.length() < nOffset + nLth )
      {
         nLth = s2.length() - nOffset;
      }

      s = s2.substring( nOffset, nOffset + nLth );
      return s;
   }

   public int zstrncpyoffset( StringBuilder sb, String s2, int nLth, int nOffset )
   {
      if ( s2.length() < nOffset + nLth )
      {
         nLth = s2.length() - nOffset;
      }

      sb.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      sb.append( s2.substring( nOffset, nOffset + nLth ) );
      return sb.length();
   }

   protected static final String zstrncpy( String s, String s2, int nLth )
   {
      if ( s2.length() < nLth )
      {
         nLth = s2.length();
      }

      s = s2.substring( 0, nLth );
      return s;
   }

   protected static final int zstrncpy( StringBuilder sb, int nOffset, String s, int nLth )
   {
      int k;

      if ( s.length() < nLth )
      {
         nLth = s.length();
      }

      for ( k = 0; k < nLth; k++ )
      {
         sb.insert( nOffset++, s.charAt( k ) );
      }

      return nOffset;  // current used length of charBuffer
   }

   protected static final int zstrncpy( CharBuffer cb, int nOffset, String s, int nLth )
   {
      int k;

      if ( s.length() < nLth )
      {
         nLth = s.length();
      }

      for ( k = 0; k < nLth; k++ )
      {
         cb.put( nOffset++, s.charAt( k ) );
      }

      return nOffset;  // current used length of charBuffer
   }

   protected static final void zmemset( StringBuilder sb, char c, int nLth )
   {
      int k;

      for ( k = 0; k < nLth; k++ )
      {
         sb.insert( k, c );
      }
   }

   protected static final void zmemset( StringBuilder sb, int nOffset, char c, int nLth )
   {
      int k;

      for ( k = 0; k < nLth; k++ )
      {
         sb.insert( k + nOffset, c );
      }
   }

   protected static final int zstrlen( String string )
   {
      return (string == null) ? 0 : string.length( );
   }

   protected static final int zstrlen( StringBuilder sb )
   {
      return (sb == null) ? 0 : sb.length( );
   }

   protected static final int zGetStringLen( String string )
   {
      return (string == null) ? 0 : string.length( );
   }

   protected static final int zGetStringLen( StringBuilder sb )
   {
      return (sb == null) ? 0 : sb.length( );
   }

   // Remove whitespace at the beginning and end of a string.
   protected static final String zstrtrim( String stringSource )
   {
      return stringSource.trim( );
   }

   // Remove leading and trailing blanks.
   protected static final int zGetStringWithoutBlank( String string, StringBuilder sbValueClean )
   {
      sbValueClean.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      if ( StringUtils.isBlank( string ) == false )
      {
         sbValueClean.append( string.trim( ) ); // returns a copy of the string, with leading and trailing whitespace omitted.
      }

      return 0;
   }

   // Remove leading and trailing blanks.
   protected static final int zGetStringLenWithoutBlank( String string )
   {
      if ( StringUtils.isBlank( string ) )
      {
         return 0;
      }

      string = string.trim();
      int len = string.length();

      return len;
   }

   protected static final int zViewIsUpdateable( View view )
   {
	  // TODO - put code in for this. used in mFAProf.vml
      return ( 0 );
   }
   protected static final int zRemoveAllBlanks( String courseNumberIn, StringBuilder sbCourseNumberOut, int maxLth )
   {
      sbCourseNumberOut.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      sbCourseNumberOut.append( StringUtils.deleteWhitespace( courseNumberIn ) );
      return 0;
   }

   protected static final String zToUpper( String srcString )
   {
      return srcString.toUpperCase( );
   }

   protected static final String zToUpper( String srcString, String tgtString )
   {
      return srcString.toUpperCase( );
   }

   protected static final int zToUpper( String srcString, StringBuilder sbTarget )
   {
      sbTarget.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      if ( StringUtils.isEmpty( srcString ) == false )
      {
         sbTarget.append( srcString.toUpperCase( ) );
      }

      return 0;
   }

   protected static final int zSearchSubString( String searchString, String subString, String direction, int startPosition )
   {
      if ( direction.startsWith( "B" ) )
      {
         return searchString.lastIndexOf( subString, startPosition - 1 );
      }
      else
      {
         return searchString.indexOf( subString, startPosition - 1 );
      }
   }

   protected static final String zstrstr( String searchString, String subString )
   {
      int position = searchString.indexOf( subString );
      if ( position >= 0 )
      {
         return searchString.substring( position );
      }
      else
      {
         return null;
      }
   }

   protected static final String zstrstr( String searchString, int nOffset, String subString )
   {
      int position = searchString.indexOf( subString, nOffset );
      if ( position >= 0 )
      {
         return searchString.substring( position );
      }
      else
      {
         return null;
      }
   }

   protected static final int zstrstr( StringBuilder sbString, int nOffset, String subString )
   {
      return sbString.indexOf( subString, nOffset );
   }

   protected static final int zstrchr( String searchString, int nOffset, char searchChar )
   {
      return searchString.indexOf( searchChar, nOffset );
   }

   protected static final int zstrchr( String searchString, char searchChar )
   {
      return searchString.indexOf( searchChar );
   }

   protected static final int zstrchr( StringBuilder sbSearchString, char searchChar )
   {
      return sbSearchString.toString( ).indexOf( searchChar );
   }

   protected static final int zstrrchr( String searchString, char searchChar )
   {
      return searchString.lastIndexOf( searchChar );
   }

   protected static final int zstrcmp( String string1, String string2 )
   {
      // KJS 10/31/13 - When I do a "IF "aaaa" <= "bbbb"", this should return > 0 but it's returning -1 so I am
	  // switching the strings.
      //return string1.compareTo( string2 );
      return string2.compareTo( string1 );
   }

   protected static final int zstrncmp( String string1, String string2, int nLth )
   {
      if ( nLth > 0 )
      {
          // KJS 10/31/13 - When I do a "IF "aaaa" <= "bbbb"", this should return > 0 but it's returning -1 so I am
    	  // switching the strings.
          //return string1.substring( 0, nLth ).compareTo( string2.substring( 0, nLth ) );
          return string2.substring( 0, nLth ).compareTo( string1.substring( 0, nLth ) );
      }
      else
      {
          // KJS 10/31/13 - When I do a "IF "aaaa" <= "bbbb"", this should return > 0 but it's returning -1 so I am
    	  // switching the strings.
          //return string1.compareTo( string2 );
          return string2.compareTo( string1 );
      }
   }

   protected static final int zstrnicmp( String string1, String string2, int nLth )
   {
      // KJS 10/31/13 - When I do a "IF "aaaa" <= "bbbb"", this should return > 0 but it's returning -1 so I am
 	  // switching the strings.
      //return string1.substring( 0, nLth - 1 ).compareToIgnoreCase( string2.substring( 0, nLth - 1 ) );
      return string2.substring( 0, nLth - 1 ).compareToIgnoreCase( string1.substring( 0, nLth - 1 ) );
   }

   protected static final int zstrcmpi( String string1, String string2 )
   {
      // KJS 10/31/13 - When I do a "IF "aaaa" <= "bbbb"", this should return > 0 but it's returning -1 so I am
 	  // switching the strings.
      //return string1.compareToIgnoreCase( string2 );
      return string2.compareToIgnoreCase( string1 );
   }

   protected static final String zSearchAndReplace( String tgtString, int tgtLth, String searchString, String replaceString )
   {
      StringBuilder sb = new StringBuilder( tgtString );
      int position = sb.indexOf( searchString );
      while ( position >= 0 )
      {
         //sbString.replace( position, position + searchString.length( ) - 1, replaceString );
         sb.replace( position, position + searchString.length( ), replaceString );

         position = position + replaceString.length();
         position = sb.indexOf( searchString, position );
      }

      return sb.toString( );
   }

   protected static final int zSearchAndReplace( StringBuilder sbString, int tgtLth, String searchString, String replaceString )
   {
      int position = sbString.indexOf( searchString );
      while ( position >= 0 )
      {
         //sbString.replace( position, position + searchString.length( ) - 1, replaceString );
         sbString.replace( position, position + searchString.length( ), replaceString );

         position = position + replaceString.length();
         position = sbString.indexOf( searchString, position );
      }

      return sbString.length( );
   }

   protected static final String zltoa( int value )
   {
      return Integer.toString( value, 10 );
   }

   protected static final String zltoa( int value, String string )
   {
      return Integer.toString( value, 10 );
   }

   protected static final String zIntegerToString( String string, int length, int value )
   {
      string = Integer.toString( value, 10 );
      if ( string.length( ) > length )
      {
         string = string.substring( 0, length );
      }

      return string;
   }

   public static final int zIntegerToString( StringBuilder sb, int length, int value )
   {
      String s = "";

      sb.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      s = zIntegerToString( s, length, value );
      sb.append( s ) ;

      return 0;
   }

   protected static final int zatol( String string )
   {
      return Integer.parseInt( string );
   }

   protected static final int zStringToInteger( String string )
   {
      return Integer.parseInt( string );
   }

   protected static final String zGetFirstEntityNameForView( View view, String entityName )
   {
      return view.getLodDef( ).getEntityDef( 0 ).getName( );
   }

   protected static final String zGetNextEntityNameForView( View view, String entityName )
   {
      int k;
      int nCnt = view.getLodDef( ).getEntityCount( );

      for ( k = 0; k < nCnt; k++ )
      {
         if ( view.getLodDef( ).getEntityDef( k ).getName( ).compareTo( entityName ) == 0 )
         {
            if ( k < nCnt - 1 )
            {
               return view.getLodDef( ).getEntityDef( k + 1 ).getName( );
            }
         }
      }

      return view.getLodDef( ).getEntityDef( 0 ).getName( );
   }

   protected static final String zGetFirstAttributeNameForEntity( View view, String entityName, String attributeName )
   {
      EntityDef ve = view.getLodDef( ).getEntityDef( entityName );
      if ( ve == null )
      {
         return null;
      }

      return ve.getAttribute( 0 ).getName( );
   }

   protected static final String zGetNextAttributeNameForEntity( View view, String entityName, String attributeName )
   {
      EntityDef ve = view.getLodDef( ).getEntityDef( entityName );
      if ( ve == null )
         return null;

      int nCnt = ve.getAttributeCount( );
      int k;

      for ( k = 0; k < nCnt; k++ )
      {
         if ( ve.getAttribute( k ).getName( ).compareTo( attributeName ) == 0 )
         {
            if ( k < nCnt - 1 )
            {
               return ve.getAttribute( k + 1 ).getName( );
            }
         }
      }

      return ve.getAttribute( 0 ).getName( );
   }

   protected static final int zDateIsLeapYear( String date )
   {
      // TODO
      return 0;
   }

   /////////////////////////////////////////////////////////////////////////////
   //
   // Function Name:  zLeft
   // Author:         ASE
   // Date:           13.December 2001
   // last changed:   15.January 2002
   //
   // description:    puts the 'nbrLeft' leftmost characters of 'String' in 'ResultString'.
   //                 if 'nbrLeft' exceeds the Input Strings' length, 'nbrLeft' will be
   //                 reduced to the String's actual length.
   //
   // parameters:     stringIn     - Input String
   //                 nbrLeft      - Number of characters to copy
   //                 resultString    - Output/Result String
   //                 resultStringLth - Initial length of the Output String
   //                                   ResultString is going to be null-terminated, so
   //                                   the ResultString has to be 1 byte larger than the
   //                                   Number of characters to copy
   //
   // returns:         0           - successful
   //                  -1           - failed: ResultString too short
   //
   /////////////////////////////////////////////////////////////////////////////
   public int
   zLeft( String stringIn, int nbrLeft, StringBuilder sbResult, int resultStringLth )
   {
      // check if 'nbrLeft' is within range
      if ( nbrLeft > zstrlen( stringIn ) )
      {
         nbrLeft = zstrlen( stringIn );
      }

      // check if ResultString is large enough
      if ( resultStringLth < (nbrLeft + 1) )
      {
         return 0;
      }

      // copy and append terminating null
      sbResult.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      sbResult.append( stringIn.substring( 0, nbrLeft - 1 ) );

      return sbResult.length( );
   }

   //
   //  PARAMETERS: strOne       - Compare string1.
   //              strOneIdx    - The index into target at which comparing will begin. Note that
   //                             Zeidon Strings are indexed starting at 1 rather than 0.
   //              strOneMaxCompare - The maximum number of characters to be compared in the target string
   //                             (including the null terminator).  If this is 0, then set it to be
   //                             the length of the target string.
   //              strTwo       - Compare string2.
   //              strTwoIdx    - The index into source at which comparing will begin. Note that
   //                             Zeidon Strings are indexed starting at 1 rather than 0.
   //              strTwoMaxCompare - The maximum number of characters to be compared in the source string
   //                             (including the null terminator).  If this is 0, then compare until
   //                             the end of the source, target, or maxReceive, whichever comes first.
   //              maxCompareLth - The maximum length of the compare INCLUDING the null terminator
   //                             (i.e.  if the target buffer is defined as:  zCHAR szTgtBuff[ 33 ];
   //                             maxTgtLth should be 33).  It is guaranteed by this operation that
   //                             the length of the compare will not exceed maxTgtLth.
   //
   //    There are a couple defaults. If maxReceive is 0, then compare to the target until the end of
   //    the target, never exceeding maxTargetLth. If maxCompare is 0, then compare until the end of
   //    the source, target, or maxReceive; whichever comes first.
   //
   //  RETURNS:    -1  - Source string < Target string
   //               0  - Source string = Target string
   //               1  - Source string > Target string
   //              -2  - maxReceive is negative
   //              -3  - maxCompare is negative
   //              -4  - maxReceive exceeds maxTargetLth
   //              -5  - Invalid parameters (null string pointers or 0 indexes)
   //
   // Where szKeyRole could be "Dual" or "D" ... either should compare equal ...
   // if ( ZeidonStringCompare( szKeyRole, 1, 0, "D", 1, 0, 2 ) == 0 )
   //
   protected int ZeidonStringCompare( String strOne,
                                      int    strOneIdx,
                                      int    strOneMaxCompare,
                                      String strTwo,
                                      int    strTwoIdx,
                                      int    strTwoMaxCompare,
                                      int    maxCompareLth )
   {
      int  nRC;

      // Ensure all parms sync up and that strOneIdx + strOneMaxReceive is less than maxCompareLth.
      if ( maxCompareLth <= 0 )
      {
         SysMessageBox( null, "JOE System Error",
                        "ZeidonStringCompare: Maximum compare length is not greater than zero.", 1 );
         return( qMAXRECEIVEISNEGATIVE );
      }

      if ( strOneMaxCompare < 0 )
      {
         SysMessageBox( null, "JOE System Error",
                        "ZeidonStringCompare: String One has negative length.", 1 );
         return( qMAXRECEIVEISNEGATIVE );
      }

      if ( strTwoMaxCompare < 0 )
      {
         SysMessageBox( null, "JOE System Error",
                        "ZeidonStringCompare: String Two has negative length.", 1 );
         return( qMAXCOPYISNEGATIVE );
      }

      if ( (strOneIdx + strOneMaxCompare) > maxCompareLth )
      {
         SysMessageBox( null, "JOE System Error",
                        "ZeidonStringCompare: strOne string is too short.", 1 );
         return( qMAXRECEIVEISNEGATIVE );
      }

      if ( StringUtils.isBlank( strOne ) && StringUtils.isBlank( strTwo ) )
      {
         return 0;  // considered to be the same (empty)
      }

      strOneIdx--;  // convert 1-based index to 0-based index
      strTwoIdx--;
      maxCompareLth--;
      if ( strOneIdx < 0 || strTwoIdx < 0 ||      // 0-based index
           (strOne == null && strOneIdx > 0) ||   // gotta have strings
           (strTwo == null && strTwoIdx > 0) ||
           (strOne != null && strOneIdx > strOne.length( )) ||
           (strTwo != null && strTwoIdx > strTwo.length( )) )
      {
         SysMessageBox( null, "JOE System Error",
                        "ZeidonStringCompare: Invalid parameter.", 1 );
         return( qINVALIDPARAMETER );
      }

      String string1 = null;
      String string2 = null;

      if ( strOneMaxCompare <= 0 )
      {
         string1 = (strOne == null) ? "" : strOne.substring( strOneIdx );
      }
      else
      {
         string1 = (strOne == null) ? "" : strOne.substring( strOneIdx, strOneIdx + strOneMaxCompare );
      }

      if ( strTwoMaxCompare <= 0 )
      {
         string2 = (strTwo == null) ? "" : strTwo.substring( strTwoIdx );
      }
      else
      {
         string2 = (strTwo == null) ? "" : strTwo.substring( strTwoIdx, strTwoMaxCompare );
      }

      //string1 = (strTwo == null) ? "" : strTwo.substring( strTwoIdx );
      //string2 = (strOne == null) ? "" : strOne.substring( strOneIdx );
      int string1Lth = string1.length( );
      int string2Lth = string2.length( );

      // KJS 10/06/11 - Running into a situation where the comparison of "3,950" and "3,950.00" are being compare
      // as equal because the strOneMaxReceive and strTwoMaxReceive are both zero which then compares both to
      // the least length (5).
      if ( string1Lth <= maxCompareLth && string2Lth <= maxCompareLth )
      {
         nRC = zstrcmp( string1, string2 );
      }
      else
      {
         // KJS 10/12/11 - Should we ever really get here?  Do we really want to use the max length
         // of the first string anywhere???!!!
         string1 = string1.substring( 0, maxCompareLth < string1Lth ? maxCompareLth : string1Lth );
         string2 = string2.substring( 0, maxCompareLth < string2Lth ? maxCompareLth : string2Lth );

//       // If strOneMaxReceive is the default of 0 then strOneMaxReceive is really (string2Lth - strOneIdx).
//       if ( strOneMaxReceive == 0 )
//          strOneMaxReceive = string2Lth;
//
//       if ( strTwoMaxReceive == 0 )
//          strTwoMaxReceive = string1Lth < strOneMaxReceive ? string1Lth : strOneMaxReceive;
//       else
//          strTwoMaxReceive = string1Lth < strOneMaxReceive ? (strTwoMaxReceive < strOneMaxReceive ? strTwoMaxReceive : strOneMaxReceive) : (strTwoMaxReceive < string1Lth ? strTwoMaxReceive : string1Lth);
//
//       // Compare the lesser of strOneMaxReceive or strTwoMaxReceive.
//       int nbrToCompare = (strOneMaxReceive < strTwoMaxReceive) ? strOneMaxReceive : strTwoMaxReceive;
//       if ( nbrToCompare < string1Lth || nbrToCompare < string2Lth )
//          nRC = zstrncmp( string1, string2, nbrToCompare );
//       else
             nRC = zstrcmp( string1, string2 );
      }

      nRC = nRC == 0 ? 0 : nRC > 0 ? 1 : -1;
      return nRC;
   }

   protected int ZeidonStringCompare( StringBuilder sbTarget,
                                      int    targetIdx,
                                      int    maxReceive,
                                      String source,
                                      int    sourceIdx,
                                      int    maxCompare,
                                      int    maxTargetLth )
   {
      return ZeidonStringCompare( sbTarget.toString(), targetIdx, maxReceive,
                                  source.toString(), sourceIdx, maxCompare, maxTargetLth );
   }

   protected int ZeidonStringCompare( String target,
                                      int    targetIdx,
                                      int    maxReceive,
                                      StringBuilder sbSource,
                                      int    sourceIdx,
                                      int    maxCompare,
                                      int    maxTargetLth )
   {
      return ZeidonStringCompare( target.toString(), targetIdx, maxReceive,
                                  sbSource.toString(), sourceIdx, maxCompare, maxTargetLth );
   }

   protected int ZeidonStringCompare( StringBuilder sbTarget,
                                      int    targetIdx,
                                      int    maxReceive,
                                      StringBuilder sbSource,
                                      int    sourceIdx,
                                      int    maxCompare,
                                      int    maxTargetLth )
   {
      return ZeidonStringCompare( sbTarget.toString(), targetIdx, maxReceive,
                                  sbSource.toString(), sourceIdx, maxCompare, maxTargetLth );
   }

   //  PARAMETERS: sbTarget      - The resultant string (copied into).
   //              targetIdx     - The index into the string at which copying
   //                              will begin. Note that Zeidon Strings are
   //                              indexed starting at 1 rather than 0.
   //              maxReceive    - The maximum number of characters permitted
   //                              in the target string (including the null
   //                              terminator).  If this is 0, then copy until
   //                              the target is full or the end of the source,
   //                              whichever comes first.  If this is a -1, we
   //                              will move the characters into the target
   //                              string, without a null character at end.
   //              sbSource      - The source string of the copy.
   //              sourceIdx     - The index into the string at which reading
   //                              will begin.  Note that Zeidon Strings are
   //                              indexed starting at 1 rather than 0.
   //              maxCopy       - The maximum number of characters to copy
   //                              from the source string.  If this is 0, then
   //                              copy until the end of the source, target, or
   //                              maxCopy, whichever comes first.
   //              maxTargetLth  - The maximum length of the target string
   //                              INCLUDING the null terminator (i.e.  if the
   //                              target buffer is defined as:
   //                                     zCHAR szTgtBuff[ 33 ];
   //                              maxTargetLth should be 33).  It is guaranteed
   //                              by this operation that the length of the
   //                              result string + 1 (for the null terminator)
   //                              will not exceed maxTargetLth.
   //
   public int ZeidonStringCopy( StringBuilder sbTarget,
                                int    targetIdx,
                                int    maxReceive,
                                StringBuilder sbSource,
                                int    sourceIdx,
                                int    maxCopy,
                                int    maxTargetLth )
   {
      int  nRC;
      int nbrToCopy;
      int lth;

      if ( sbTarget == null || sbSource == null ||     // gotta have strings
           targetIdx == 0 || sourceIdx == 0 )          // 1-based index
      {
         SysMessageBox( null, "JOE System Error",
                        "ZeidonStringCopy: Invalid parameter.", 1 );
         return( qINVALIDPARAMETER );
      }

      targetIdx--;  // convert 1-based index to 0-based index for
      sourceIdx--;

      // Ensure all parms sync up and that targetIdx + maxReceive is less than maxTargetLth.
      if ( maxReceive < -1 )
      {
         SysMessageBox( null, "JOE System Error",
                        "ZeidonStringCopy: Target string has negative length", 1 );
         return( qMAXRECEIVEISNEGATIVE );
      }

      if ( maxCopy < 0 )
      {
         return( qMAXCOPYISNEGATIVE );
      }

      if ( (targetIdx + maxReceive) > maxTargetLth )
      {
         SysMessageBox( null, "JOE System Error",
                        "ZeidonStringCopy: Target string is too small", 1 );
         return( qMAXRECEIVEEXCEEDSTARGETLEN );
      }

      // Ensure the source index does not point beyond the end of the source string.
      if ( sourceIdx > zstrlen(sbSource) )
      {
         SysMessageBox( null, "JOE System Error",
                        "ZeidonStringCopy: Invalid parameter (source index).", 1 );
         return( qINVALIDPARAMETER );
      }

      // If maxReceive is -1, move the characters to the target without a null at end.
      if ( maxReceive == -1 )
      {
         if ( maxCopy == 0 )
         {
            maxCopy = maxTargetLth - targetIdx - 1;
         }

         while ( sourceIdx < sbSource.length( ) && sbSource.charAt( sourceIdx ) != '\0' && maxCopy > 0 )
         {
            sbTarget.setCharAt( targetIdx++, sbSource.charAt( sourceIdx++ ) );
            maxCopy--;
         }

         return( sbTarget.length( ) );
      }

      // If maxReceive is the default of 0 then the Max is really
      // maxTargetLth - targetIdx - 1 (for zero-based index).
      if ( maxReceive == 0 )
      {
         maxReceive = maxTargetLth - targetIdx - 1;
      }

      if ( maxCopy == 0 )
      {
         maxCopy = maxReceive;
      }

      // Copy the lesser of maxReceive or maxCopy.
      nbrToCopy = (maxReceive < maxCopy) ? maxReceive : maxCopy;
      lth = sbSource.length( ) - sourceIdx;
      if ( lth < nbrToCopy )
      {
         nbrToCopy = lth; // remove the "+ 1" from the original C ... requested by Kelly  2011.10.27
      }

      sbTarget.setLength( targetIdx + nbrToCopy );
      while ( sourceIdx < sbSource.length( ) && sbSource.charAt( sourceIdx ) != '\0' && nbrToCopy > 0 )
      {
         sbTarget.setCharAt( targetIdx++, sbSource.charAt( sourceIdx++ ) );
         nbrToCopy--;
      }

   // sbTarget.setCharAt( targetIdx, '\0' );
      return sbTarget.length( );

/*
      // Currently ZeidonStringCopy is being generated with the targetIdx and sourceIdx as 1.
      // The start of a string is 0.
      if ( targetIdx > 0 )
         targetIdx--;

      if ( sourceIdx > 0 )
         sourceIdx--;

      if ( maxTargetLth > 0 )
         maxTargetLth--;

      if ( maxReceive == 0 )
       maxReceive = maxTargetLth;

      if ( maxCopy == 0 && sbSource != null )
       maxCopy = sbSource.length( );

      if ( sbSource != null )
         sbTarget.replace( targetIdx, maxReceive, sbSource.substring( sourceIdx, maxCopy ) );
      // target.replace( targetIdx, -1, source.substring( sourceIdx ) );

      nRC = sbTarget.length( );
      if ( nRC > maxTargetLth )
      {
         sbTarget.setLength( maxTargetLth );
         nRC = maxTargetLth;
      }

      return nRC;
*/
   }

   protected int ZeidonStringCopy( StringBuilder sbTarget,
                                   int    targetIdx,
                                   int    maxReceive,
                                   String source,
                                   int    sourceIdx,
                                   int    maxCopy,
                                   int    maxTargetLth )
   {
      int  nRC;
      StringBuilder sb;

      if ( source == null )
      {
         sb = new StringBuilder( );
      }
      else
      {
         sb = new StringBuilder( source );
      }

      nRC = ZeidonStringCopy( sbTarget, targetIdx, maxReceive, sb, sourceIdx, maxCopy, maxTargetLth );

      return nRC;
   }

   protected String ZeidonStringCopy( String target,
                                      int    targetIdx,
                                      int    maxReceive,
                                      StringBuilder sbSource,
                                      int    sourceIdx,
                                      int    maxCopy,
                                      int    maxTargetLth )
   {
      int  nRC;
      StringBuilder sb;

      if ( target == null )
      {
         sb = new StringBuilder( );
      }
      else
      {
         sb = new StringBuilder( target );
      }

      nRC = ZeidonStringCopy( sb, targetIdx, maxReceive, sbSource, sourceIdx, maxCopy, maxTargetLth );

      return sb.toString( );
   }

   protected String ZeidonStringCopy( String target,
                                      int    targetIdx,
                                      int    maxReceive,
                                      String source,
                                      int    sourceIdx,
                                      int    maxCopy,
                                      int    maxTargetLth )
   {
      int  nRC;

      StringBuilder sbTgt = new StringBuilder( );
      StringBuilder sbSrc = new StringBuilder( );
      if ( target != null )
      {
         sbTgt.append( target );
      }

      if ( source != null )
      {
         sbSrc.append( source );
      }

      ZeidonStringCopy( sbTgt, targetIdx, maxReceive, sbSrc, sourceIdx, maxCopy, maxTargetLth );

      nRC = sbTgt.length( );
      return sbTgt.toString( );
   }

   protected StringBuilder ZeidonStringConcat( StringBuilder sbTarget,
                                               int    targetIdx,
                                               int    maxReceive,
                                               StringBuilder sbSource,
                                               int    sourceIdx,
                                               int    maxCopy,
                                               int    maxTargetLth )
   {
      if ( sbSource != null )
      {
         if ( sourceIdx > 0 )
         {
            sbTarget.append( sbSource.substring( sourceIdx - 1 ) );
         }
         else
         {
            sbTarget.append( sbSource );
         }
      }

      // RESULT = sbTarget.length( );
      return sbTarget;
   }

   protected StringBuilder ZeidonStringConcat( StringBuilder sbTarget,
                                               int    targetIdx,
                                               int    maxReceive,
                                               String source,
                                               int    sourceIdx,
                                               int    maxCopy,
                                               int    maxTargetLth )
   {
      if ( sourceIdx > 0 )
      {
         sbTarget.append( source.substring( sourceIdx - 1 ) );
      }
      else
      {
         sbTarget.append( source );
      }

   // RESULT = sbTarget.length( );
      return sbTarget;
   }

   protected String ZeidonStringConcat( String target,
                                        int    targetIdx,
                                        int    maxReceive,
                                        StringBuilder sbSource,
                                        int    sourceIdx,
                                        int    maxCopy,
                                        int    maxTargetLth )
   {
      if ( sourceIdx > 0 )
      {
         target = target + sbSource.substring( sourceIdx - 1 );
      }
      else
      {
         target = target + sbSource;
      }

   // nRC = target.length();
      return target;
   }

   protected String ZeidonStringConcat( String target,
                                        int    targetIdx,
                                        int    maxReceive,
                                        String source,
                                        int    sourceIdx,
                                        int    maxCopy,
                                        int    maxTargetLth )
   {
      if ( targetIdx > 0 )
      {
         targetIdx--;
      }

      if ( sourceIdx > 0 )
      {
         sourceIdx--;
      }

      if ( source != null )
      {
         if ( sourceIdx > 0 )
         {
            target = target + source.substring( sourceIdx );
         }
         else
         {
            target = target + source;
         }
      }

   // RESULT = target.length( );
      return target;
   }

   protected int ZeidonStringConvertFromNumber( StringBuilder sbSuffix, int stringIndex, int maxSourceLth,
                                                int maxTargetLth, int intValue, double dblValue, String convType )
   {
      // ZeidonStringConvertFromNumber( STRING /* Target String */,
      //        INTEGER /* String Index */,
      //        INTEGER /* Max Receive Length */,
      //        INTEGER /* Max String Length */,
      //        INTEGER /* Integer Value to Convert */,
      //        DOUBLE /* Decimal Value to Convert */,
      //        STRING /* Type of Conversion - Integer or Decimal */ )

      if ( convType.equals( "I" ) )
      {
         zstrcpy( sbSuffix, intValue );
      }
      else
      {
         zstrcpy( sbSuffix, dblValue );
      }

      return sbSuffix.length( );
   }

   protected int ZeidonStringConvertFromNumber( StringBuilder sbSuffix, int stringIndex, int maxSourceLth,
                                                int maxTargetLth, int intValue, int nValue, String convType )
   {
      // ZeidonStringConvertFromNumber( STRING /* Target String */,
      //        INTEGER /* String Index */,
      //        INTEGER /* Max Receive Length */,
      //        INTEGER /* Max String Length */,
      //        INTEGER /* Integer Value to Convert */,
      //        DOUBLE /* Decimal Value to Convert */,
      //        STRING /* Type of Conversion - Integer or Decimal */ )

      if ( convType.equals( "I" ) )
      {
         zstrcpy( sbSuffix, intValue );
      }
      else
      {
         zstrcpy( sbSuffix, nValue );
      }

      return sbSuffix.length( );
   }

   //  RETURNS: zCURSOR_NULL - Entity cursor is NULL
   //           zCURSOR_SET  - Entity position established on first entity
   //           zCALL_ERROR  - Error in call
   protected int SetCursorFirstEntity( View view, String entityName, String scopingEntity )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      nRC = cursor.setFirst( scopingEntity ).toInt();

      return nRC;
   }

   //  RETURNS: zCURSOR_NULL - Entity cursor is NULL
   //           zCURSOR_SET  - Entity position established on next entity
   //           zCALL_ERROR  - Error in call
   protected int SetCursorNextEntity( View view, String entityName, String scopingEntity )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      nRC = cursor.setNext( scopingEntity ).toInt();

      return nRC;
   }

   //  RETURNS: zCURSOR_NULL - Entity cursor is NULL
   //           zCURSOR_SET  - Entity position established on previous entity
   //           zCALL_ERROR  - Error in call
   protected int SetCursorPrevEntity( View view, String entityName, String scopingEntity )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      nRC = cursor.setPrev( scopingEntity ).toInt();

      return nRC;
   }

   //  RETURNS: zCURSOR_NULL - Entity cursor is NULL
   //           zCURSOR_SET  - Entity position established on last entity
   //           zCALL_ERROR  - Error in call
   protected int SetCursorLastEntity( View view, String entityName, String scopingEntity )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      nRC = cursor.setLast( scopingEntity ).toInt();

      return nRC;
   }

   protected int SetCursorFirstEntityByAttribute( View   view,
                                                  String entityName,
                                                  String attributeName,
                                                  String value,
                                                  String scopingEntity )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.hasAny( scopingEntity ) == false )
      {
         nRC = zCURSOR_NULL;
      }
      else
      {
         nRC = cursor.setFirst( attributeName, value, scopingEntity ).toInt();
      }

      return nRC;
   }

   protected int SetCursorFirstEntityByAttr( View   tgtView,
                                             String tgtEntity,
                                             String tgtAttribute,
                                             View   srcView,
                                             String srcEntity,
                                             String srcAttribute,
                                             String scopingEntity )
   {
      int    nRC;

      EntityCursor cursor = tgtView.cursor( tgtEntity );
      if ( cursor.hasAny( scopingEntity ) == false )
      {
         nRC = zCURSOR_NULL;
      }
      else
      {
         String value = srcView.cursor( srcEntity ).getAttribute( srcAttribute ).getString();
         nRC = cursor.setFirst( tgtAttribute, value, scopingEntity ).toInt();
      }

      return nRC;
   }

   protected int SetCursorNextEntityByAttr( View   tgtView,
                                            String tgtEntity,
                                            String tgtAttribute,
                                            View   srcView,
                                            String srcEntity,
                                            String srcAttribute,
                                            String scopingEntity )
   {
      int    nRC;

      EntityCursor cursor = tgtView.cursor( tgtEntity );
      if ( cursor.hasAny( scopingEntity ) == false )
      {
         nRC = zCURSOR_NULL;
      }
      else
      {
         String value = srcView.cursor( srcEntity ).getAttribute( srcAttribute ).getString();
      // nRC = cursor.setFirst( tgtAttribute, value, scopingEntity ).toInt();
         nRC = cursor.setFirst( scopingEntity ).toInt();
      }

      return nRC;
   }

   //  RETURNS: zCURSOR_NULL      - No entity instances exist
   //           zCURSOR_UNCHANGED - Entity cursor unchanged
   //           zCURSOR_SET       - Entity position established
   //           zCALL_ERROR       - Error in call
   public int SetCursorFirstEntityByEntityCsr( View tgtView, String tgtEntityName,
                                               View srcView, String srcEntityName, String scopingEntity )
   {
      EntityCursor tgtCursor = tgtView.cursor( tgtEntityName );
      EntityCursor srcCursor = srcView.cursor( srcEntityName );
      if ( tgtCursor.hasAny( scopingEntity ) == false || srcCursor.isNull() )
      {
         return zCURSOR_NULL;
      }

      EntityInstance original = tgtCursor.getEntityInstance(); // Save original in case we don't find a match.
      for ( CursorResult rc = tgtCursor.setFirst( scopingEntity );
            rc.isSet();
            rc = tgtCursor.setNextContinue() )
      {
          if ( tgtCursor.isLinked( srcCursor ) )
          {
              // We found what we want so return.
              return CursorResult.SET.toInt();
          }
      }

      tgtCursor.setCursor( original ); // Reset back to the original.
      return CursorResult.UNCHANGED.toInt();
   }

   //  RETURNS: zCURSOR_NULL          - No entity instances exist
   //           zCURSOR_UNCHANGED     - Entity cursor unchanged
   //           zCURSOR_SET           - Entity position established
   //           zCURSOR_SET_NEWPARENT - Entity position changed within new parent
   //           zCALL_ERROR           - Error in call
   protected int SetCursorNextEntityByEntityCsr( View tgtView, String tgtEntityName,
                                                 View srcView, String srcEntityName, String scopingEntity )
   {
      EntityCursor tgtCursor = tgtView.cursor( tgtEntityName );
      EntityCursor srcCursor = srcView.cursor( srcEntityName );
      if ( tgtCursor.hasAny( scopingEntity ) == false || srcCursor.isNull() )
      {
         return zCURSOR_NULL;
      }

      EntityInstance original = tgtCursor.getEntityInstance(); // Save original in case we don't find a match.
      CursorResult rc = tgtCursor.setNextContinue( );
      while ( rc.isSet() )
      {
          if ( tgtCursor.isLinked( srcCursor ) )
          {
              // We found what we want so return.
              return CursorResult.SET.toInt();
          }

          rc = tgtCursor.setNextContinue( );
      }

      tgtCursor.setCursor( original ); // Reset back to the original.
      return CursorResult.UNCHANGED.toInt();
   }

   public int SetCursorScopeOI( View view, String entityName, int pos )
   {
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.hasAny() )
      {
         if ( pos == zPOS_FIRST )
         {
            return cursor.setFirstWithinOi().toInt();
         }
         else
         if ( pos == zPOS_NEXT )
         {
            return cursor.setNextWithinOi().toInt();
         }
      // else
      // if ( pos == zPOS_PREVIOUS )
      //    return cursor.setPreviousWithinOi();
      }

      return zCURSOR_NULL;
   }

   //  RETURNS: zCURSOR_NULL          - No entity instances exist
   //           zCURSOR_UNCHANGED     - Entity cursor unchanged
   //           zCURSOR_SET           - Entity position established
   //           zCURSOR_SET_NEWPARENT - Entity position changed within new parent
   //           zCALL_ERROR           - Error in call

   protected final int zSCOPE_OI = 1;

   protected int SetEntityCursor( View     view,
                                  String   entityName,
                                  String   attributeName,
                                  int      lControl,
                                  double   dDecimalSearchValue,
                                  String   srcEntityName,
                                  String   srcAttributeName,
                                  int      relativePosition,
                                  String   scopingEntity,
                                  String   contextName )
   {
      if ( (lControl & (zQUAL_STRING + zQUAL_INTEGER)) != 0 )
      {
         TraceLineS( "SetEntityCursor Control Error ... Decimal looking for ", (lControl & zQUAL_STRING) == 0 ? "String" : "Integer" );
         return zCALL_ERROR;
      }

      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.hasAny( scopingEntity ) == false )
      {
         return zCURSOR_NULL;
      }

      boolean bTestCsrResult = (lControl & zTEST_CSR_RESULT) != 0;
      boolean bQualScopeOI = (lControl & zQUAL_SCOPE_OI) != 0;
      lControl &= 0x7;
      if ( bTestCsrResult )
      {
         if ( bQualScopeOI )
         {
            if ( lControl == zPOS_FIRST || lControl == zPOS_LAST )
            {
               return cursor.hasAnyWithinOi( attributeName, dDecimalSearchValue ) ? zCURSOR_SET : zCURSOR_NULL;
            }
            else
            if ( lControl == zPOS_NEXT )
            {
               return cursor.hasNext( ) ? zCURSOR_SET : zCURSOR_UNCHANGED;
            }
            else
            if ( lControl == zPOS_PREV )
            {
               return cursor.hasPrev( ) ? zCURSOR_SET : zCURSOR_UNCHANGED;
            }
            else
            {
               // error!!!
            }
         }
         else
         {
            if ( lControl == zPOS_FIRST || lControl == zPOS_LAST )
            {
               return cursor.hasAny( attributeName, dDecimalSearchValue, scopingEntity ) ? zCURSOR_SET : zCURSOR_NULL;
            }
            else
            if ( lControl == zPOS_NEXT )
            {
               return cursor.hasNext( ) ? zCURSOR_SET : zCURSOR_UNCHANGED;
            }
            else
            if ( lControl == zPOS_PREV )
            {
               return cursor.hasPrev( ) ? zCURSOR_SET : zCURSOR_UNCHANGED;
            }
            else
            {
               // error!
            }
         }
      }
      else
      {
         if ( bQualScopeOI )
         {
            if ( lControl == zPOS_FIRST )
            {
               return cursor.setFirstWithinOi( attributeName, dDecimalSearchValue ).toInt();
            }
            else
            if ( lControl == zPOS_NEXT )
            {
               return cursor.setNextWithinOi( ).toInt();
            }
            else
            if ( lControl == zPOS_PREV )
            {
               return cursor.setPrevWithinOi( ).toInt();
            }
            else
            if ( lControl == zPOS_LAST )
            {
               return cursor.setLastWithinOi( attributeName, dDecimalSearchValue ).toInt();
            }
            else
            {
               // error!!!
            }
         }
         else
         {
            if ( lControl == zPOS_FIRST )
            {
               return cursor.setFirst( attributeName, dDecimalSearchValue, scopingEntity ).toInt();
            }
            else
            if ( lControl == zPOS_NEXT )
            {
               return cursor.setNext( attributeName, dDecimalSearchValue, scopingEntity ).toInt();

            }
            else
            if ( lControl == zPOS_PREV )
            {
               return cursor.setPrev( attributeName, dDecimalSearchValue, scopingEntity ).toInt();
            }
            else
            if ( lControl == zPOS_LAST )
            {
               return cursor.setLast( attributeName, dDecimalSearchValue, scopingEntity ).toInt();
            }
            else
            {
               // error
            }
         }
      }

      return zCURSOR_NULL;
   }

   protected int SetEntityCursor( View     view,
                                  String   entityName,
                                  String   attributeName,
                                  int      lControl,
                                  int      lIntegerSearchValue,
                                  String   srcEntityName,
                                  String   srcAttributeName,
                                  int      relativePosition,
                                  String   scopingEntity,
                                  String   contextName )
   {
      if ( (lControl & (zQUAL_STRING + zQUAL_DECIMAL)) != 0 )
      {
         TraceLineS( "SetEntityCursor Control Error ... Integer looking for ", (lControl & zQUAL_STRING) == 0 ? "String" : "Decimal" );
         return zCALL_ERROR;
      }

      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.hasAny( scopingEntity ) == false )
      {
         return zCURSOR_NULL;
      }

      boolean bTestCsrResult = (lControl & zTEST_CSR_RESULT) != 0;
      boolean bQualScopeOI = (lControl & zQUAL_SCOPE_OI) != 0;
      lControl &= 0x7;
      if ( bTestCsrResult )
      {
         if ( bQualScopeOI )
         {
            if ( lControl == zPOS_FIRST || lControl == zPOS_LAST )
            {
               return cursor.hasAnyWithinOi( attributeName, lIntegerSearchValue ) ? zCURSOR_SET : zCURSOR_NULL;
            }
            else
            if ( lControl == zPOS_NEXT )
            {
               return cursor.hasNext( ) ? zCURSOR_SET : zCURSOR_UNCHANGED;
            }
            else
            if ( lControl == zPOS_PREV )
            {
               return cursor.hasPrev( ) ? zCURSOR_SET : zCURSOR_UNCHANGED;
            }
            else
            {
               // error!!!
            }
         }
         else
         {
            if ( lControl == zPOS_FIRST || lControl == zPOS_LAST )
            {
               return cursor.hasAny( attributeName, lIntegerSearchValue, scopingEntity ) ? zCURSOR_SET : zCURSOR_NULL;
            }
            else
            if ( lControl == zPOS_NEXT )
            {
               return cursor.hasNext( ) ? zCURSOR_SET : zCURSOR_UNCHANGED;
            }
            else
            if ( lControl == zPOS_PREV )
            {
               return cursor.hasPrev( ) ? zCURSOR_SET : zCURSOR_UNCHANGED;
            }
            else
            {
               // error!
            }
         }
      }
      else
      {
         if ( bQualScopeOI )
         {
            if ( lControl == zPOS_FIRST )
            {
               return cursor.setFirstWithinOi( attributeName, lIntegerSearchValue ).toInt();
            }
            else
            if ( lControl == zPOS_NEXT )
            {
               return cursor.setNextWithinOi( ).toInt();
            }
            else
            if ( lControl == zPOS_PREV )
            {
               return cursor.setPrevWithinOi( ).toInt();
            }
            else
            if ( lControl == zPOS_LAST )
            {
               return cursor.setLastWithinOi( attributeName, lIntegerSearchValue ).toInt();
            }
            else
            {
               // error!!!
            }
         }
         else
         {
            if ( lControl == zPOS_FIRST )
            {
               return cursor.setFirst( attributeName, lIntegerSearchValue, scopingEntity ).toInt();
            }
            else
            if ( lControl == zPOS_NEXT )
            {
               return cursor.setNext( attributeName, lIntegerSearchValue, scopingEntity ).toInt();
            }
            else
            if ( lControl == zPOS_PREV )
            {
               return cursor.setPrev( attributeName, lIntegerSearchValue, scopingEntity ).toInt();
            }
            else
            if ( lControl == zPOS_LAST )
            {
               return cursor.setLast( attributeName, lIntegerSearchValue, scopingEntity ).toInt();
            }
            else
            {
               // error
            }
         }
      }

      return zCURSOR_NULL;
   }

   protected int SetEntityCursor( View     view,
                                  String   entityName,
                                  String   attributeName,
                                  int      lControl,
                                  String   stringSearchValue,
                                  String   srcEntityName,
                                  String   srcAttributeName,
                                  int      relativePosition,
                                  String   scopingEntity,
                                  String   contextName )
   {
      if ( (lControl & (zQUAL_INTEGER + zQUAL_DECIMAL)) != 0 )
      {
         TraceLineS( "SetEntityCursor Control Error ... String looking for ", (lControl & zQUAL_INTEGER) == 0 ? "Integer" : "Decimal" );
         return zCALL_ERROR;
      }

      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.hasAny( scopingEntity ) == false )
      {
         return zCURSOR_NULL;
      }

      boolean bTestCsrResult = (lControl & zTEST_CSR_RESULT) != 0;
      boolean bQualScopeOI = (lControl & zQUAL_SCOPE_OI) != 0;
      lControl &= 0x7;
      if ( bTestCsrResult )  // we're testing the cursor ... not setting it!
      {
         if ( bQualScopeOI )
         {
            if ( lControl == zPOS_FIRST || lControl == zPOS_LAST )
            {
               if ( StringUtils.isEmpty( stringSearchValue ) )
               {
                  return cursor.hasAnyWithinOi( ) ? zCURSOR_SET : zCURSOR_NULL;
               }
               else
               {
                  return cursor.hasAnyWithinOi( attributeName, stringSearchValue ) ? zCURSOR_SET : zCURSOR_NULL;
               }
            }
            else
            if ( lControl == zPOS_NEXT )
            {
               return cursor.hasNext( ) ? zCURSOR_SET : zCURSOR_UNCHANGED;
            }
            else
            if ( lControl == zPOS_PREV )
            {
               return cursor.hasPrev( ) ? zCURSOR_SET : zCURSOR_UNCHANGED;
            }
            else
            {
                // error!!!
            }
         }
         else
         {
            if ( lControl == zPOS_FIRST || lControl == zPOS_LAST )
            {
               if ( StringUtils.isEmpty( stringSearchValue ) )
               {
                  return cursor.hasAny( scopingEntity ) ? zCURSOR_SET : zCURSOR_NULL;
               }
               else
               {
                  return cursor.hasAny( attributeName, stringSearchValue, scopingEntity ) ? zCURSOR_SET : zCURSOR_NULL;
               }
            }
            else
            if ( lControl == zPOS_NEXT )
            {
               return cursor.hasNext( ) ? zCURSOR_SET : zCURSOR_UNCHANGED;
            }
            else
            if ( lControl == zPOS_PREV )
            {
               return cursor.hasPrev( ) ? zCURSOR_SET : zCURSOR_UNCHANGED;
            }
            else
            {
               // error!
            }
         }
      }
      else  // we're not testing the cursor ... setting it!
      {
         if ( bQualScopeOI )
         {
            if ( lControl == zPOS_FIRST )
            {
               if ( StringUtils.isEmpty( stringSearchValue ) )
               {
                  return cursor.setFirstWithinOi( ).toInt();
               }
               else
               {
                  return cursor.setFirstWithinOi( attributeName, stringSearchValue ).toInt();
               }
            }
            else
            if ( lControl == zPOS_NEXT )
            {
               return cursor.setNextWithinOi( ).toInt();
            }
            else
            if ( lControl == zPOS_PREV )
            {
               return cursor.setPrevWithinOi( ).toInt();
            }
            else
            if ( lControl == zPOS_LAST )
            {
               if ( StringUtils.isEmpty( stringSearchValue ) )
               {
                  return cursor.setLastWithinOi( ).toInt();
               }
               else
               {
                  return cursor.setLastWithinOi( attributeName, stringSearchValue ).toInt();
               }
            }
            else
            {
               // error!
            }
         }
         else
         {
            if ( StringUtils.isEmpty( stringSearchValue ) )
            {
               if ( lControl == zPOS_FIRST )
               {
                  return cursor.setFirst( scopingEntity ).toInt();
               }
               else
               if ( lControl == zPOS_NEXT )
               {
                  return cursor.setNext( ).toInt(); // , scopingEntity );
               }
               else
               if ( lControl == zPOS_PREV )
               {
                  return cursor.setPrev( ).toInt(); // , scopingEntity );
               }
               else
               if ( lControl == zPOS_LAST )
               {
                  return cursor.setLast( scopingEntity ).toInt();
               }
            }
            else
            {
               if ( lControl == zPOS_FIRST )
               {
                  return cursor.setFirst( attributeName, stringSearchValue, scopingEntity ).toInt();
               }
               else
               if ( lControl == zPOS_NEXT )
               {
                  return cursor.setNext( attributeName, stringSearchValue, scopingEntity ).toInt(); // , scopingEntity );
               }
               else
               if ( lControl == zPOS_PREV )
               {
                  return cursor.setPrev( attributeName, stringSearchValue, scopingEntity ).toInt(); // , scopingEntity );
               }
               else
               if ( lControl == zPOS_LAST )
               {
                  return cursor.setLast( attributeName, stringSearchValue, scopingEntity ).toInt();
               }
               else
               {
                  // error
               }
            }
         }
      }

      return zCURSOR_NULL;
   }

   public int TraceLineS( String label, String text )
   {
      task.log().info( label + " " + text );
      return 0;
   }

   public int TraceLineI( String label, int i )
   {
      return TraceLineS( label, Integer.toString( i ) );
   }

   public int TraceLine( String strFormat, Object... arr )
   {
      String tgtString = String.format( strFormat, arr );
      return TraceLineS( tgtString, "" );
   }

   //  RETURNS: Entity key
   //           0 on error (cursor undefined, etc.)
   protected int GetEntityKey( View view, String entityName )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = 0;
      }
      else
      {
         nRC = (int) cursor.getEntityKey( );
      }

      return nRC;
   }

   //  RETURNS:    0           - Length successfully retrieved
   //              zCALL_ERROR - Error retrieving length
   protected int GetAttributeLength( MutableInt miLth, View view, String entityName, String attributeName )
   {
      int nRC;
      int nLth;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = zCALL_ERROR;
         nLth = 0;
      }
      else
      {
         nLth = cursor.getEntityDef( ).getAttribute( attributeName ).getLength( );
         nRC = 0;
      }

       miLth.setValue( nLth );
       return nRC;
   }

   //  RETURNS:    0           - Length successfully retrieved
   //              zCALL_ERROR - Error retrieving length
   protected int GetAttributeDisplayLength( int nAttributeLth, View view,
                                            String entityName, String attributeName, String contextName )
   {
      // TODO ... DG, this is probably not the correct length.
      int nLth;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nLth = zCALL_ERROR;
      }
      else
      {
         nLth = cursor.getEntityDef( ).getAttribute( attributeName ).getLength( );
      }

      return nLth;
   }

   //  RETURNS:    0           - Attribute successfully retrieved
   //              -1          - Returned 0 in lplReturnInteger, the attribute value was null.
   //              zCALL_ERROR - Error retrieving attribute
   protected int GetIntegerFromAttribute( View view, String entityName, String attributeName )
   {
      Integer k;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         k = 0;
      }
      else
      {
         //k = cursor.getAttribute( attributeName ).getInteger();
         AttributeInstance attrib = cursor.getAttribute( attributeName );
         k = attrib.getInteger();
         if ( k == null )
         {
            k = 0;
         }
      }

      return k;
   }

   protected int GetIntegerFromAttribute( MutableInt i, View view, String entityName, String attributeName )
   {
      int nRC;
      Integer k;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         k = 0;
         nRC = zCALL_ERROR;
      }
      else
      {
         //k = cursor.getAttribute( attributeName ).getInteger();
         AttributeInstance attrib = cursor.getAttribute( attributeName );
         k = attrib.getInteger();
         if ( k == null )
         {
            k = 0;
            nRC = -1;
         }
         else
         {
            nRC = 0;
         }
      }

      i.setValue( k );
      return k;
   }

   protected int GetIntegerFromAttribute( int i, View view, String entityName, String attributeName )
   {
      return GetIntegerFromAttribute( view, entityName, attributeName );
   }

   //  RETURNS:    0           - Attribute successfully retrieved
   //              -1          - Returned null string in pchReturnString, the attribute value was null.
   //              -2          - Returned null string in pchReturnString, the entity was null.
   //              zCALL_ERROR - Error retrieving attribute
   protected String GetStringFromAttribute( View view, String entityName, String attributeName )
   {
      String s;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         s = "";
      }
      else
      {
         AttributeInstance attrib = cursor.getAttribute( attributeName );
         s = attrib.getString();


         /*  dgc 2013-08-10 This shouldn't be necessary because it's handled by the domain.  If there's
          * an error then it is in the domain, not here.

         // Because in our vml code we compare a null to "", we should return a "" instead of null.
         if ( s == null )
         {
            s = "";
         }
         */
      }

      return s;
   }

   protected String GetStringFromAttribute( String string, View view, String entityName, String attributeName )
   {
      String s = "";

      // Following kept calling recursive.
      //return GetStringFromAttribute( s, view, entityName, attributeName );
      return GetStringFromAttribute( view, entityName, attributeName );
   }

   protected int GetStringFromAttribute( StringBuilder sbReturn, View view, String entityName, String attributeName )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = -2;
         sbReturn.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      }
      else
      {
         AttributeInstance attr = cursor.getAttribute( attributeName );
         String s;
         s = attr.getString();

         if ( s == null )
         {
            s = "";
            nRC = -1;
         }
         else
         {
             nRC = 0;
         }

         sbReturn.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
         sbReturn.append( s );
      }

      return nRC;
   }

   //  RETURNS:    0           - Address successfully retrieved
   //              zCALL_ERROR - Error retrieving attribute
   protected String GetAddrForAttribute( String string, View view, String entityName, String attributeName )
   {
      return GetStringFromAttribute( string, view, entityName, attributeName );
   }

   //  RETURNS:     0          - Attribute successfully retrieved
   //              -1          - Returned null string in pchReturnString, the attribute value was null.
   //              -2          - Returned null string in pchReturnString, the entity was null.
   //              zCALL_ERROR - Error retrieving attribute
   protected String GetStringFromAttributeByContext( String returnString, View view, String entityName, String attributeName,
                                                     String context, int length )
   {
      String s;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         s = "";
      }
      else
      {
         s = cursor.getAttribute( attributeName ).getString( context );

         // Because in our vml code we compare a null to "", we should return a "" instead of null.
         if ( s == null )
         {
            s = "";
         }
      }

      return s;
   }

   protected StringBuilder GetStringFromAttributeByContext( StringBuilder sbReturn, View view,
                                                            String entityName, String attributeName,
                                                            String context, int maxLength )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = -2;
         sbReturn.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      }
      else
      {
         String s = cursor.getAttribute( attributeName ).getString( context );
         if ( s == null )
         {
            s = "";
            nRC = -1;
         }
         else
         {
            nRC = 0;
         }

         sbReturn.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
         sbReturn.append( s );

      }

      return sbReturn;
   }

   //  RETURNS:    0           - Attribute successfully retrieved
   //              -1          - Returned 0 in lpdReturnDecimal, the attribute value was null.
   //              zCALL_ERROR - Error retrieving attribute
   protected int GetDecimalFromAttribute( MutableDouble returnDecimalValue, View view,
                                          String entityName, String attributeName )
   {
      int nRC;
      Double d;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = zCALL_ERROR;
         d = 0.0;
      }
      else
      {
         d = cursor.getAttribute(attributeName).getDouble();
         if ( d == null )
         {
            nRC = -1;
            d = 0.0;
         }
         else
         {
            nRC = 0;
         }
      }

      returnDecimalValue.setValue( d );
      return nRC;
   }

   protected Double GetDecimalFromAttribute( Double decimalValue, View view,
                                             String entityName, String attributeName )
   {
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         decimalValue = 0.0;
      }
      else
      {
         decimalValue = cursor.getAttribute( attributeName ).getDouble();
      }

      // KJS 05/26/10 - Having a problem in my derived attribute when this returns a null.
      if ( decimalValue == null )
      {
         decimalValue = 0.0;
      }

      return decimalValue;
   }

   protected int SysConvertDecimalToString( Object dDecimalValue, StringBuilder sbReturn, int ulNumberOfDecimals )
   {
      sbReturn.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      String s = dDecimalValue.toString();

      // If string has a decimal point, truncate it.
      int idx = s.indexOf( '.' );
      if ( idx > -1 )
      {
         s = s.substring( 0, Math.min( s.length( ) - 1, idx + ulNumberOfDecimals ) );
      }

      sbReturn.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      sbReturn.append( s );
      return 0;
   }

   protected int SysConvertStringToDecimal( String stringValue, MutableDouble returnDouble )
   {
      returnDouble.setValue( Double.parseDouble( stringValue ) );
      return 0;
   }

   //  RETURNS:    1 - Attr > decimal
   //              0 - Attributes are logically equal
   //             -1 - Attr < decimal
   //    zCALL_ERROR - Error in call
   protected int CompareAttributeToDecimal( View view, String entityName, String attributeName, double d )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         return zCALL_ERROR;
      }
      else
      {
         Double d1 = cursor.getAttribute( attributeName ).getDouble();
         if ( d1 == null )
         {
            d1 = 0.0;
         }

         if ( d1 > d )
         {
            return 1;
         }
         else
         if ( d1 < d )
         {
            return -1;
         }
         else
         {
            return 0;
         }
      }
   }

   //
   // lpVariable       - pointer to the variable to receive the the attribute value.
   // pulReturnLth     - Used to return the length of blobs.
   // cVariableType    - Zeidon data type, indicates what lpVariable pointer to.
   // ulVariableLth    - Indicates length of variable that is pointed to by lpVariable.
   //                    Only used when cVariableType is zTYPE_STRING or zTYPE_BLOB.
   // lpView           - View to Object instance
   // cpcEntityName    - Entity name containing the attribute to get
   // cpcAttributeName - Attribute name to retrieve.
   // cpcContextName   - Optional context name, used in conjunction
   //                    with the domain associated with the specified attribute.
   // nFlag            - Should be set to zACCEPT_NULL_ENTITY, if user wants to allow
   //                    a return code of zNULL_ENTITY, otherwise should be 0. If this
   //                    flag is zero and the entity is null, a zCALL_ERROR is returned.
   //                    zUSE_DEFAULT_CONTEXT indicates that the default Context of the
   //                    Domain associated with the attribute will be used in processing
   //                    this request.  Any value specified by the cpcContextName
   //                    parameter is ignored.
   //
   // RETURNS: zVAR_SET     (0)  - Attribute successfully retrieved
   //          zVAR_NULL    (-1) - Indicates that the attribute value is a null value
   //          zENTITY_NULL (-2) - Indicates that the entity is null ... only returned when
   //                              zACCEPT_NULL_ENTITY (1) is specified in the control parameter.
   //          zCALL_ERROR       - error updating attribute
   protected int GetVariableFromAttribute( StringBuilder sb, MutableInt returnLth, char variableType, int variableLth, View view,
                                           String entityName, String attributeName, String context, int control )
   {
      sb.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.

      EntityCursor cursor = view.cursor( entityName );
      // KJS 01/29/16 - If the entity cursor is null, then this would send back zCALL_ERROR but didn't throw and error.
      // Don C is thinking that we should throw the error because we shouldn't be trying to get the attribute if the cursor
      // is null. If we want to reverse back... take out the "&& (contro...".
      if ( cursor.isNull() && (control == zACCEPT_NULL_ENTITY)  )
      {
         returnLth.setValue( 0 );
         return (control & zACCEPT_NULL_ENTITY) != 0 ? zENTITY_NULL : zCALL_ERROR;
      }
      else
      {
         String s;
         if ( StringUtils.isBlank( context ) && control != zUSE_DEFAULT_CONTEXT )
         {
             s = cursor.getAttribute( attributeName ).getString();
         }
         else
         {
             s = cursor.getAttribute( attributeName ).getString( context );
         }

         if ( s == null )
         {
            returnLth.setValue( 0 );
            return zVAR_NULL;
         }

         if ( variableLth > 0 )
         {
            variableLth--;
         }

         // DKS 2013.01.18 re-activated the test for variable length.
         // KJS 10/20/11 - I am commenting out these lines because they are causing
         // me problems because getStringFromArribute is returning the external value not
         // internal when there is no context.
         if ( variableLth > 0 && variableLth < s.length( ) )
         {
            sb.append( s.substring( 0, variableLth ) );
         }
         else
         {
            sb.append( s );
         }

         returnLth.setValue( sb.length( ) );
         return zVAR_SET;
      }
   }

   protected int GetVariableFromAttribute( StringBuilder sb, int returnLth, char variableType, int variableLth, View view,
                                           String entityName, String attributeName, String context, int control )
   {
      MutableInt i = new MutableInt( returnLth );
      return GetVariableFromAttribute( sb, i, variableType, variableLth, view, entityName, attributeName, context, control );
   }

   protected String GetVariableFromAttribute( String s, int returnLth, char variableType, int variableLth, View view,
                                              String entityName, String attributeName, String context, int control )
   {
      StringBuilder sb = new StringBuilder();
      MutableInt i = new MutableInt( returnLth );
      GetVariableFromAttribute( sb, i, variableType, variableLth, view, entityName, attributeName, context, control );
      return sb.toString();
   }

   protected String GetVariableFromAttribute( int returnLth, char variableType, int variableLth, View view,
                                              String entityName, String attributeName, String context, int control )
   {
      StringBuilder sb = new StringBuilder();
      MutableInt i = new MutableInt( returnLth );
      GetVariableFromAttribute( sb, i, variableType, variableLth, view, entityName, attributeName, context, control );
      return sb.toString();
   }

   protected int GetVariableFromAttribute( MutableInt lValue, int returnLth, char variableType, int variableLth, View view,
                                           String entityName, String attributeName, String context, int control )
   {
      int nRC;
      int i;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         i = 0;
         nRC = zCURSOR_NULL;
      }
      else
      {
         if ( StringUtils.isBlank( context ) )
         {
             i = cursor.getAttribute( attributeName ).getInteger();
         }
         else
         {
             i = cursor.getAttribute( attributeName ).getInteger( context );
         }

         nRC = 0;
      }

      lValue.setValue( i );
      return nRC;
   }

   protected int GetVariableFromAttribute( int returnValue, int returnLth, char variableType, int variableLth, View view,
                                           String entityName, String attributeName, String context, int control )
   {
      MutableInt i = new MutableInt( );
      GetVariableFromAttribute( i, returnLth, variableType, variableLth, view, entityName, attributeName, context, control );
      return i.intValue();
   }

   //  RETURNS: zCURSOR_NULL         Cursor position for Entity is NULL
   //           zCURSOR_UNDEFINED    Cursor position for Entity is undefined
   //           zCURSOR_SET          Cursor position for Entity is set
   //           zCALL_ERROR          Error in call
   protected int CheckExistenceOfEntity( View view, String entityName )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      nRC = cursor.checkExistenceOfEntity().toInt();
      return nRC;
   }

   //  RETURNS:    0           - Entity Instance created
   //              zCALL_ERROR - Error creating entity instance
   protected int CreateEntity( View view, String entityName, int pos )
   {
      view.cursor( entityName ).createEntity( CURSOR_POS.get( pos ) );
      return 0;
   }

   //  RETURNS:    zCURSOR_... - Entity deleted, and this is the status for setting the cursor.
   //                            These return codes are shown under the operations for SetCursor...Entity.
   //              zCALL_ERROR - Error deleting entity instance
   protected int DeleteEntity( View view, String entityName, int pos )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = zCALL_ERROR;
      }
      else
      {
         nRC = cursor.deleteEntity( CURSOR_POS.get( pos ) ).toInt();
      }

      return nRC;
   }

   //  RETURNS:    0           - Attributes successfully set
   //              zCALL_ERROR - Error setting attributes
   protected int SetMatchingAttributesByName( View tgtView, String tgtEntity,
                                              View srcView, String srcEntity, int control )
   {
      int nRC;
      EntityCursor tgtCursor = tgtView.cursor( tgtEntity );
      EntityCursor srcCursor = srcView.cursor( srcEntity );
      if ( tgtCursor.isNull() || srcCursor.isNull() )
      {
         return zCALL_ERROR;
      }

      EnumSet flags = EnumSet.noneOf( SetMatchingFlags.class );
      if ( (control & zSET_KEYS) != 0 )
      {
          flags.add( SetMatchingFlags.fSET_KEYS );
      }

      if ( (control & zSET_NOTNULL) != 0 )
      {
          flags.add( SetMatchingFlags.fSET_NOTNULL );
      }

      if ( (control & zSET_SRCNOTNULL) != 0 )
      {
          flags.add( SetMatchingFlags.fSET_SRCNOTNULL );
      }

      nRC = tgtCursor.setMatchingAttributesByName( srcView.getCursor( srcEntity ), flags );

      return nRC;
   }

   // RETURNS:    0 - Attribute value has been set
   //   zCALL_ERROR - Error in call
   protected int StoreValueInRecord( View view, String entityName, String attributeName, Object value, int length )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = zCALL_ERROR;
      }
      else
      {
         nRC = 0;
         //if ( value instanceof DateTime )
         //    return externalValue;
         cursor.getAttribute( attributeName ).setValue( value );
      }

      return 0;
   }

   protected int StoreStringInRecord( View view, String entityName, String attributeName, String value )
   {
      return StoreValueInRecord( view, entityName, attributeName, value, 0 );
   }

   //  RETURNS: zCURSOR_NULL      - No entity instances exist
   //           zCURSOR_UNCHANGED - Entity cursor unchanged
   //           zCURSOR_SET       - Entity position established
   //           zCALL_ERROR       - Error in call
   protected int SetCursorFirstEntityByString( View view, String entityName, String attributeName, String stringValue, String scopingEntity )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.hasAny( scopingEntity ) == false )
      {
         nRC = zCURSOR_NULL;
      }
      else
      {
         nRC = cursor.setFirst( attributeName, stringValue, scopingEntity ).toInt();
      }

      return nRC;
   }

   //  RETURNS: zCURSOR_NULL          - No entity instances exist
   //           zCURSOR_UNCHANGED     - Entity cursor unchanged
   //           zCURSOR_SET           - Entity position established
   //           zCURSOR_SET_NEWPARENT - Entity position changed within new parent
   //           zCALL_ERROR           - Error in call
   protected int SetCursorNextEntityByString( View view, String entityName, String attributeName, String stringValue, String scopingEntity )
   {
      // TODO - need setNext using scopingEntity???
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.hasAny( scopingEntity ) == false )
      {
         nRC = zCURSOR_NULL;
      }
      else
      {
         nRC = cursor.setNext( attributeName, stringValue, scopingEntity ).toInt();
      }

      return nRC;
   }

   //  RETURNS: zCURSOR_NULL      - No entity instances exist
   //           zCURSOR_UNCHANGED - Entity cursor unchanged
   //           zCURSOR_SET       - Entity position established
   //           zCALL_ERROR       - Error in call
   public static int  SetCursorFirstEntityByInteger( View view, String entityName, String attributeName, int lID, String scopingEntity )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.hasAny( scopingEntity ) == false )
      {
         nRC = zCURSOR_NULL;
      }
      else
      {
         nRC = cursor.setFirst( attributeName, lID, scopingEntity ).toInt();
      }

      return nRC;
   }

   //  RETURNS: zCURSOR_NULL          - No entity instances exist
   //           zCURSOR_UNCHANGED     - Entity cursor unchanged
   //           zCURSOR_SET           - Entity position established
   //           zCURSOR_SET_NEWPARENT - Entity position changed within new parent
   //           zCALL_ERROR           - Error in call
   public static int  SetCursorNextEntityByInteger( View view, String entityName, String attributeName, int lID, String scopingEntity )
   {
      // TODO - need setNext using scopingEntity???
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.hasAny( scopingEntity ) == false )
      {
         nRC = zCURSOR_NULL;
      }
      else
      {
         nRC = cursor.setNext( attributeName, lID, scopingEntity ).toInt(); // , scopingEntity );
      }

      return nRC;
   }

   //  RETURNS:    1 - Attr > string
   //              0 - Attributes are logically equal
   //             -1 - Attr < string
   //            -16 - Error in call
   protected int CompareAttributeToString( View view, String entityName, String attributeName, String value )
   {
      EntityCursor cursor = view.cursor( entityName );

      if ( cursor.isNull() )
      {
         return zCURSOR_NULL;
      }
      else
      {
         int nRC = cursor.getAttribute( attributeName ).compare( value );
         return nRC == 0 ? 0 : nRC > 0 ? 1 : -1;
      }
   }

   protected int CompareAttributeToString( View view, String entityName, String attributeName, StringBuilder sbValue )
   {
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         return zCURSOR_NULL;
      }
      else
      {
         int nRC = cursor.getAttribute( attributeName ).compare( sbValue.toString( ) );
         return nRC == 0 ? 0 : nRC > 0 ? 1 : -1;
      }
   }

   //  RETURNS:    1 - Attr > integer
   //              0 - Attributes are logically equal
   //             -1 - Attr < integer
   //            -16 - Error in call
   protected int CompareAttributeToInteger( View view, String entityName, String attributeName, Integer value )
   {
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         return zCURSOR_NULL;
      }
      else
      {
         int nRC = cursor.getAttribute( attributeName ).compare( value );
         return nRC == 0 ? 0 : nRC > 0 ? 1 : -1;
      }
   }

   //  RETURNS:    1 - Target attr > source attr
   //              0 - Attributes are logically equal
   //             -1 - Target attr < source attr
   //            -16 - Error in call
   protected int CompareAttributeToAttribute( View view1, String entityName1, String attributeName1, View view2, String entityName2, String attributeName2 )
   {
      EntityCursor cursor1 = view1.cursor( entityName1 );
      EntityCursor cursor2 = view2.cursor( entityName2 );
      if ( cursor1.isNull() || cursor2.isNull() )
      {
         return zCURSOR_NULL;
      }
      else
      {
         int nRC = cursor1.getAttribute( attributeName1 ).compare( cursor2.getAttribute( attributeName2 ) );
         return nRC == 0 ? 0 : nRC > 0 ? 1 : -1;
      }
   }

   protected int DropObjectInstance( View view )
   {
      view.drop();
   // view = null;
      return 0;
   }

   //  RETURNS:    0           - Attribute successfully set
   //              zCALL_ERROR - Error updating attribute
   protected int SetAttributeFromString( View view, String entityName, String attributeName, String value)
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = zCALL_ERROR;
      }
      else
      {
         nRC = 0;
         cursor.getAttribute( attributeName ).setValue( value );
      }

      return nRC;
   }

   protected int SetAttributeFromString( View view, String entityName, String attributeName, StringBuilder sbValue )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = zCURSOR_NULL;
      }
      else
      {
         nRC = 0;
         cursor.getAttribute( attributeName ).setValue( sbValue.toString( ) );
      }

      return nRC;
   }

   //  RETURNS:    0           - Attribute successfully set
   //              zCALL_ERROR - Error updating attribute
   protected int SetAttributeFromInteger( View view, String entityName, String attributeName, int value )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = zCALL_ERROR;
      }
      else
      {
         nRC = 0;
         cursor.getAttribute( attributeName ).setValue( value );
      }

      return nRC;
   }

   //  RETURNS:    0           - Attribute successfully set
   //              zCALL_ERROR - Error updating attribute
   protected int SetAttributeFromDecimal( View view, String entityName, String attributeName, double value )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = zCALL_ERROR;
      }
      else
      {
         nRC = 0;
         cursor.getAttribute( attributeName ).setValue( value );
      }

      return nRC;
   }

   //  RETURNS:    0           - Attribute successfully set
   //              zCALL_ERROR - Error updating attribute
   protected int SetAttributeFromAttribute( View tgtView, String tgtEntity, String tgtAttribute,
                                            View srcView, String srcEntity, String srcAttribute )
   {
      int nRC;
      EntityCursor tgtCursor = tgtView.cursor( tgtEntity );
      EntityCursor srcCursor = srcView.cursor( srcEntity );
      if ( tgtCursor.isNull( ) || srcCursor.isNull( ) )
      {
         nRC = zCURSOR_NULL;
      }
      else
      {
         nRC = 0;
         tgtCursor.getAttribute( tgtAttribute).setValue( srcView.cursor( srcEntity ).getAttribute( srcAttribute ).getValue() )  ;
      }

      return nRC;
   }

   // RETURNS: 0           - Attribute successfully set
   //          zCALL_ERROR - error updating attribute
   protected int SetAttributeFromVariable( View view, String entityName, String attributeName, Object value,
                                           char variableType, int maxLth, String contextName, int control )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = zCURSOR_NULL;
      }
      else
      {
         nRC = 0;
         cursor.getAttribute( attributeName ).setValue( value, contextName );
      }

      return nRC;
   }

   protected int AddToAttributeFromDecimal( View view, String entityName, String attributeName, double journalActual )
   {
      // TODO DG???
      return 0;
   }

   protected int SetAttributeFromCurrentDateTime( View view, String entityName, String attributeName )
   {
      // TODO - Create code.
      return 0;
   }

   //  RETURNS:    0           - Entity Attributes successfully set
   //              zCALL_ERROR - Error updating attribute
   protected int SetBlobFromOI( View view, String entityName, String attributeName, View srcView, int control )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = zCALL_ERROR;
      }
      else
      {
         nRC = 0;
         //String blobStr = srcView.serializeOi().asJson().withIncremental().toString();
         String blobStr = srcView.serializeOi().withIncremental().toString();
         cursor.getAttribute( attributeName ).setValue( blobStr );
      }

      return nRC;
   }

   //  RETURNS:    0           - Attribute successfully set
   //              zCALL_ERROR - Error updating attribute
   protected int  SetAttributeFromBlob( View view, String entityName, String attributeName, CharBuffer blob, int blobLth )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = zCALL_ERROR;
      }
      else
      {
         nRC = 0;
         cursor.getAttribute( attributeName ).setValue( blob, "" );
      }

      return nRC;
   }

   protected int WriteBlobToFile( View view, String entityName, String attributeName, String fileName )
   {
      // TODO:  write blob to file
      return 0;
   }

   protected int PrintTextBlob( View view, String entityName, View printView,
                                String string2, String string3, String string4, int i )
   {
      // TODO Auto-generated method stub
      return 0;
   }

   protected String SysConvertDecimalToString( double decimalNbr, String returnString, int flag )
   {
      returnString = "" + decimalNbr;
   // RESULT = 0;
      return returnString;
   }

   // RETURNS: 0           - Attribute successfully changed
   //          zCALL_ERROR - error updating attribute
   protected int AddToAttributeFromVariable( View view, String entityName, String attributeName,
                                             Object value, char variableType, int maxLth,
                                             String contextName )
   {
      int nRC = 0;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = zCALL_ERROR;
      }
      else
      {
         if ( contextName.equals( "Month" ))
         {
            int nMonths = ((Number) value).intValue();
            DateTime date = view.cursor(entityName).getAttribute(attributeName).getDateTime();
            DateTime date2 = date.plusMonths(nMonths);
            view.cursor(entityName).getAttribute(attributeName).setValue( date2 );
         }
         else
         if ( contextName.equals( "Day" ))
         {
            int nDays = ((Number) value).intValue();
            DateTime date = view.cursor(entityName).getAttribute(attributeName).getDateTime();
            DateTime date2 = date.plusDays(nDays);
            view.cursor(entityName).getAttribute(attributeName).setValue( date2 );
         }
         else
         {
            cursor.getAttribute( attributeName ).add( value );
         }
      }

      return nRC;
   }

   protected int SfActivateSysEmptyOI( zVIEW returnView, String lodDefName, TaskQualification qualView, int control )
   {
      View view = null;
      try
      {
          // Try with ZeidonSystem
          view = qualView.activateEmptyObjectInstance( lodDefName, task.getSystemTask().getApplication() );
      }
      catch ( UnknownLodDefException e )
      {
          // Try with ZeidonTools
          view = qualView.activateEmptyObjectInstance( lodDefName, task.getApplication( "ZeidonTools" ) );
      }

      returnView.setView( view );
      return 0;
   }

   /**
    * Activates an OI from file.  The application for the lodDefName is either ZeidonSystem or ZeidonTools.
    *
    * @param returnView
    * @param lodDefName
    * @param qualView
    * @param fileName
    * @param control
    * @return
    */
    protected int SfActivateSysOI_FromFile( zVIEW returnView, String lodDefName, TaskQualification qualView,
                                            String fileName, int control )
    {
        View view = null;
        try
        {
            // Try with ZeidonSystem
            view = qualView.deserializeOi()
                           .fromFile( fileName )
                           .setFlags( control )
                           .setApplication( task.getSystemTask().getApplication() )
                           .setLodDef( lodDefName )
                           .activateFirst();
        }
        catch ( UnknownLodDefException e )
        {
            // Try with ZeidonTools
            view = qualView.deserializeOi()
                            .fromFile( fileName )
                            .setFlags( control )
                            .setApplication( task.getApplication( "ZeidonTools" ) )
                            .setLodDef( lodDefName )
                            .activateFirst();
        }

        returnView.setView( view );
        return 0;
    }

   //./ ADD NAME=fnValidView
   // Source Module=kzoevlaa.c
   /////////////////////////////////////////////////////////////////////////////
   //
   //  FUNCTION:   fnValidView
   //
   //  ASSUMES:    Task passed is valid
   //
   //  RETURNS:    1 - View valid
   //              0 - View invalid
   //
   /////////////////////////////////////////////////////////////////////////////
   private int fnValidView( Task task, View view )
   {
      if ( isValid( view ) )
      {
         if ( view.getTask() == task )
         {
            return 1;
         }
      }

      //  "KZOEE101 - Invalid View"
      fnIssueCoreError( task, view, 8, 101, 0, "", "" );

      return( 0 );  // return error
   }

   /**
    * Activate empty OI.  Since JOE doesn't care about the difference between single/multiple roots
    * we ignore the flag.
    */
   protected int ActivateEmptyObjectInstance( zVIEW returnView, String lodDefName, TaskQualification qual, int control )
   {
      View view = qual.activateEmptyObjectInstance( lodDefName, qual.getApplication() );
      returnView.setView( view );
      return 0;
   }

   protected int ActivateObjectInstance( zVIEW returnView, String lodDefName, View qual,
                                         View activateQualificationView, int control )
   {
      int nRC = 0;

  // if ( control == 0 )
  //     control = zASYNCHRONOUS;
      // A couple of times in Windows vml we have an activate with zSINGLE + zLEVE_APPLICATION. That is not
      // applicable in the JOE so ignore and just use zSINGLE.
      if ( control == 4 )
    	  control = 0;

      View view = qual.activateObjectInstance( lodDefName, activateQualificationView, ACTIVATE_CONTROL.get( control ) );
      LodDef lodDef = view.getLodDef();
      returnView.setView( view );
      switch ( view.cursor( lodDef.getRoot().getName() ).getEntityCount() )
      {
         case 0:
            nRC = -1;
            break;

         case 1:
            nRC = 0;
            break;

         default:
            nRC = 1;
            break;
      }

      TraceLineS( "Display object instance from ActivateObjectInstance for OD: ", view.getLodDef().getName() );
   // DisplayObjectInstance( view, "", "" );
      return nRC;
   }

   protected int ActivateObjectInstance( zVIEW returnView, String lodDefName, TaskQualification qual,
                                         View activateQualificationView, int control )
   {
      if ( ! ( qual instanceof View ) )
      {
         throw new ZeidonException( "qual is not a valid qualification view: " + qual.toString( ) );
      }

      return ActivateObjectInstance( returnView, lodDefName, ((View) qual), activateQualificationView, control );
   }

   protected int ActivateObjectInstance( zVIEW returnView, String lodDefName, TaskQualification qual, int view, int control )
   {
      return ActivateObjectInstance( returnView, lodDefName, qual, null, control );
   }

   public int ActivateOI_FromFile( zVIEW view, String lodDefName, View qualView, String fileName, int control )
   {
       view.setView( task.deserializeOi()
                         .fromFile( fileName )
                         .setLodDef( lodDefName )
                         .setFlags( control )
                         .setApplication( qualView == null ? task.getApplication() : qualView.getApplication() )
                         .activateFirst() );
      return 0;
   }

   protected int ActivateOI_FromXML_File( zVIEW view, String lodDefName, View viewToWindow, String fileName, int control )
   {
      // TODO Auto-generated method stub
      int nRC = 0; // view.activateOiFromXML_File( view, lodDefName, viewToWindow, fileName, control );
      return nRC;
   }

   protected int ActivateOI_FromOI( zVIEW returnView, View view, int control )
   {
      returnView.setView( view.activateOiFromOi( ACTIVATE_CONTROL.get( control ) ) );
      return 0;
   }

   protected int ActivateOI_FromOI( zVIEW returnView, zVIEW view, int control )
   {
      returnView.setView( view.activateOiFromOi( ACTIVATE_CONTROL.get( control ) ) );
      return 0;
   }

   protected int ActivateOI_FromOI_ForTask( zVIEW returnView, View srcView, View taskView, int control )
   {
      if ( isValid( taskView ) )
      {
         returnView.setView( taskView.activateOiFromOi( ACTIVATE_CONTROL.get( control ) ) );
      }
      else
      {
         returnView.setView( srcView.activateOiFromOi( ACTIVATE_CONTROL.get( control ) ) );
      }

      return 0;
   }

   protected int CommitOI_ToFile( View view, String fileName, int control )
   {
      view.writeOiToFile( fileName, WriteOiFlags.convertLongFlags( control ) );
      return 0;
   }

   protected int CommitOI_ToXML_File( View view, String fileName, int control )
   {
      view.writeOiToXml( fileName, WriteOiFlags.convertLongFlags( control ) );
      return 0;
   }

   //  RETURNS:   -1 - Blob is NULL.  No OI is returned.
   //              0 - Object instance activated, single root found
   //              1 - Object instance activated, multiple roots found.  If
   //                  zSINGLE was specified, only the first was activated.
   //    zCALL_ERROR - Error Activating object instance
   protected int SetOI_FromBlob( zVIEW returnView, StringBuilder sbLodDefName, TaskQualification qualView,
                                 View srcView, String srcEntity, String srcAttribute, int control )
   {
      EntityCursor cursor = srcView.cursor( srcEntity );
      if ( cursor.isNull() )
      {
         return zCALL_ERROR;
      }

      Application application = qualView.getApplication();
      //Blob blob = srcView.cursor( srcEntity ).getAttribute( srcAttribute ).getBlob();
      String strTmp = srcView.cursor( srcEntity ).getAttribute( srcAttribute ).getString();
      if ( strTmp == null )
      {
         return -1;
      }

  	// There can be more than one view but we are assuming there is only one.
  	List viewList = new DeserializeOi( qualView )
      //.asJson()
      .fromString( strTmp )
      .activate();

      for ( View v : viewList )
      {
          v.logObjectInstance();
          returnView.setView( v );
          sbLodDefName.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
          sbLodDefName.append( v.getLodDef().getName() );
      }

      /*

      View v = qualView.deserializeOi()
              .fromResource( strTmp )
              .setFlags( ACTIVATE_CONTROL.get(control) )
              .setApplication( application )
              .activateFirst();
      View v = qualView.deserializeOi()
              .fromInputStream( new ByteArrayInputStream( blob.getBytes() ) )
              .setFlags( ACTIVATE_CONTROL.get(control) )
              .setApplication( application )
              .activateFirst();
      returnView.setView( v );
      sbLodDefName.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      sbLodDefName.append( v.getLodDef().getName() );
      */

      return 0;
   }

   protected String SetOI_FromBlob( zVIEW returnView, String lodDefName, TaskQualification qualView,
                                    View srcView, String srcEntity, String srcAttribute, int control )
   {
      StringBuilder sb = new StringBuilder( 256 );

      if ( lodDefName != null )
    	  sb.append( lodDefName );
      int rc = SetOI_FromBlob( returnView, sb, qualView, srcView, srcEntity, srcAttribute, control );
      if ( rc < 0 )
      {
         return null;
      }
      else
      {
         return sb.toString( );
      }
   }

   // Not sure why but we have a lot of calls to SetOI_FromBlob where the lodDefName is
   // 0. We never seem to use this value... So I am adding this override.
   //SetOI_FromBlob( mPerson, 0, mChurch, mChurch, "ACR_BatchItem", "BlobOI", zSINGLE );
   protected String SetOI_FromBlob( zVIEW returnView, int lodDefName, TaskQualification qualView,
                                    View srcView, String srcEntity, String srcAttribute, int control )
   {
      StringBuilder sb = new StringBuilder( );
      int rc = SetOI_FromBlob( returnView, sb, qualView, srcView, srcEntity, srcAttribute, control );
      if ( rc < 0 )
      {
         return null;
      }
      else
      {
         return sb.toString( );
      }
   }

   protected int CommitObjectInstance( View view ) throws InvalidViewException
   {
	  if ( !isValid(view) )
		  throw new InvalidViewException( "Commit" );

      view.commit( );
      return 0;
   }

   // TODO - DG ... Create code if not already done.
   //./ ADD NAME=GenerateQualFromEntityList
   // Source Module=kzoeoiaa.c
   /////////////////////////////////////////////////////////////////////////////
   //
   //  ENTRY:      GenerateQualFromEntityList
   //
   //  PURPOSE:    Generates a qualification object to load all the entities in
   //              the supplied list of root entities.
   //
   //  PARAMETERS:  pvQual        - Qual view that is passed back.
   //               vEntityList   - View containing the entity list.
   //               pchEntityName - Name of the entity.
   //               pchScoping    - Scoping entity.
   //               lControl      - Not currently used.
   //
   /////////////////////////////////////////////////////////////////////////////
   public int
   GenerateQualFromEntityList( zVIEW  returnView,
                               View   vEntityList,
                               String pchEntityName,
                               String pchScoping,
                               int    lControl )
   {
       returnView.setView( QualificationBuilder.generateQualFromEntityList( vEntityList, pchEntityName, pchScoping ) );
       return 0;
   }

   protected int ObjectInstanceUpdated( View view )
   {
      return view.isUpdated() ? 1 : 0;
   }

   /**
    * Commit the views in the view cluster.
    *
    * @param viewCluster
    * @param errorIndex - ignored.
    * @return
    */
   protected int CommitMultipleObjectInstances( int viewCluster, MutableInt errorIndex )
   {
       List list = getClusterInfo().getViewList( viewCluster );
       task.getTask().commitMultipleOis( list );
       return 0;
   }

   protected int CommitMultipleObjectInstances( MutableInt viewCluster, MutableInt errorIndex )
   {
       List list = getClusterInfo().getViewList( viewCluster.getValue() );
       task.getTask().commitMultipleOis( list );
       return 0;
   }

   protected int CreateViewCluster( View viewToWindow, MutableInt viewCluster )
   {
       ClusterInfo info = getClusterInfo();
       viewCluster.setValue( info.createCluster() );
       return 0;
   }

   protected int AddToViewCluster( int viewCluster, View view, int commitFlags )
   {
       if ( commitFlags != 0 )
           throw new ZeidonException( "Commit flags not supported for AddToViewCluster" );

       if ( view instanceof zVIEW )
           view = ((zVIEW) view).getView();

       getClusterInfo().getViewList( viewCluster ).add( view );
       return 0;
   }

   protected int AddToViewCluster( MutableInt viewCluster, View view, int commitFlags )
   {
       return AddToViewCluster( viewCluster.getValue(), view, commitFlags );
   }

   protected int DropViewCluster( int viewCluster )
   {
       getClusterInfo().deleteCluster( viewCluster );
       return 0;
   }

   protected int DropViewCluster( MutableInt viewCluster )
   {
       getClusterInfo().deleteCluster( viewCluster.getValue() );
       return 0;
   }

   //  RETURNS:    0           - Temporal Subobject version successfully accepted
   //              zCALL_ERROR - Error accepting temporal version of Subobject
   protected int AcceptSubobject( View view, String entityName )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )  // Kelly ... I don't know which way to go with this one  dks 2013.02.15
         nRC = zCURSOR_NULL;
      else
      {
          cursor.acceptSubobject( );
          nRC = 0;
      }

      return nRC;
   }

   //  RETURNS:    zCURSOR_SET - The version was canceled and the cursor has been re-established on the previous version
   //              zCURSOR_UNDEFINED - The version was canceled and the temporal entity has been deleted!
   //              zCALL_ERROR - Error dropping current version of Subobject
   protected int CancelSubobject( View view, String entityName )
   {

      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = zCURSOR_NULL;
      }
      else
      {
         if ( cursor.isVersioned( ) )
         {
            cursor.cancelSubobject( );
            nRC = 0;
         }
         else
         {
            nRC = zCALL_ERROR;
         }
      }

      return nRC;
   }

   protected int DropView( View view )
   {
      view.drop( );
      return 0;
   }

   /**
    * Drop all the views in this task that reference the same OI.
    *
    * This potentially won't drop all views if there are views in other
    * tasks that reference this view but it will make some educated
    * guesses on which tasks to look.
    *
    * @param anyView
    * @param szQueryOIName
    * @param false1
    * @return
    */
   protected int DropViewObject( View anyView, String szQueryOIName, int false1 )
   {
       long id = anyView.getOiId();
       if ( anyView.getTask() != task.getTask() )
       {
           for ( View view : anyView.getTask().getViewList() )
           {
               if ( view.getOiId() == id )
                   view.drop();
           }
       }

       if ( task.getSystemTask() != task.getTask() )
       {
           for ( View view : task.getSystemTask().getViewList() )
           {
               if ( view.getOiId() == id )
                   view.drop();
           }
       }

       for ( View view : task.getTask().getViewList() )
       {
           if ( view.getOiId() == id )
               view.drop();
       }

       return 0;
   }

   //  RETURNS:  0            sort successfull
   //            zCALL_ERROR  error in call
   public static int OrderEntityForView( View view, String entityName, String orderKeys )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.hasAny() == false )
      {
         nRC = zCURSOR_NULL;
      }
      else
      {
         nRC = 0;
         cursor.orderEntities( orderKeys );
      }

      return nRC;
   }

   //  RETURNS:    zCURSOR_... - Entity deleted, and this is the status for setting the cursor.
   //                            These return codes are shown under the operations for SetCursor...Entity.
   //              zCALL_ERROR - Error excluding entity instance
   protected int ExcludeEntity( View view, String entityName, int pos )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = zCALL_ERROR;
      }
      else
      {
         nRC = 0;
         cursor.excludeEntity( CURSOR_POS.get( pos ) );
      }

      return 0;
   }

   //  RETURNS:    0           - Target subobject inclusion successful
   //              zCALL_ERROR - Error including subobject instance
   protected int IncludeSubobjectFromSubobject( View tgtView, String tgtEntityName,
                                                View srcView, String srcEntityName, int pos )
   {
      int nRC;
      EntityCursor tgtCursor = tgtView.cursor( tgtEntityName );
      EntityCursor srcCursor = srcView.cursor( srcEntityName );
      if ( srcCursor.isNull() )
      {
         nRC = zCURSOR_NULL;
      }
      else
      {
         nRC = 0;
         tgtView.cursor( tgtEntityName ).includeSubobject( srcView.cursor( srcEntityName ), CURSOR_POS.get( pos ) );
      }

      return nRC;
   }

   //  RETURNS:    0           - Entity Instance created
   //              zCALL_ERROR - Error creating entity instance
   protected int CreateTemporalEntity( View view, String entityName, int pos )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor == null ) // I'm not sure we want any test here...
      {
         nRC = zCALL_ERROR;
      }
      else
      {
         nRC = 0;
         cursor.createTemporalEntity( CURSOR_POS.get( pos ) );
      }

      return nRC;
   }

   //  RETURNS:    0           - Subobject SuccessfullyVersioned
   //              zCALL_ERROR - Error versioning Subobject
   protected int CreateTemporalSubobjectVersion( View view, String entityName )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor == null ) // I'm not sure we want any test here...
      {
         nRC = zCALL_ERROR;
      }
      else
      {
         nRC = 0;
         cursor.createTemporalSubobjectVersion( );
      }

      return nRC;
   }

   protected int SetViewReadOnly( View view )
   {
      view.setReadOnly( true );
      return 0;
   }

   protected void DisplayEntityInstance( View view, String entityName )
   {
      // TODO DG???
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() == false && cursor.checkExistenceOfEntity() == CursorResult.SET )
      {
         cursor.logEntity( true );
      }
      else
      {
         task.log().debug( "*** %s: %s", entityName, "" );
      }
   }

   protected void DisplayObjectInstance( View view, String entityName, String scopingEntity )
   {
      view.logObjectInstance( );
   }

   protected int MiSetInstanceUpdateFlag( View view, int trueFalse )
   {
      // TODO DG
      // view.setInstanceUpdated( trueFalse == 0 ? false : true );
      return 0;
   }

   //  RETURNS: 0 - instance not versioned
   //           1 - instance versioned
   //           zCALL_ERROR           - error on call
   protected int MiEntityVersioned( View view, String entityName )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = zCALL_ERROR;
      }
      else
      {
         nRC = cursor.isVersioned( ) ? 1 : 0;
      }

      return nRC;
   }

   protected int MiGetUpdateForView( View view )
   {
      int nRC = view.isReadOnly( ) ? 0 : 1;
      return nRC;
   }

   protected int MiGetObjectNameForView( StringBuilder sbObjectName, View view )
   {
      int nRC = 0;
      sbObjectName.setLength( 0 );
      sbObjectName.append( view.getLodDef( ).getName( ) );
      return 0;
   }

   protected String MiGetObjectNameForView( String strObjectName, View view )
   {
      return view.getLodDef( ).getName( );
   }

   protected void SetViewUpdate( View view )
   {
      // TODO DG
      // view.setInstanceUpdated( true );
   }

   //  RETURNS:    0 or greater  - Number of unhidden Entities.
   //              zCALL_ERROR   - Error in call
   protected int CountEntitiesForView( View view, String entityName )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.hasAny() == false )
      {
         nRC = zCALL_ERROR;
      }
      else
      {
         nRC = cursor.getEntityCount( );
      }

      return nRC;
   }

   protected String MiGetParentEntityNameForView( String stringParentEntity, View view, String entityName )
   {
      return view.getLodDef( ).getEntityDef( entityName ).getParent( ).getName( );
   }

   protected int ResetView( View view )
   {
      view.reset();
      return 0;
   }

   public static int AppendPathSeparator( StringBuilder sbDirectoryName )
   {
      char pathSeparator = File.separatorChar;
      char replaceCharacter = pathSeparator == '/' ? '\\' : '/';
      String s = sbDirectoryName.toString( );
      s = s.replace( replaceCharacter, pathSeparator );
      int nLth = s.length( );
      sbDirectoryName.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      sbDirectoryName.append( s );
      if ( nLth > 1 && sbDirectoryName.charAt( nLth - 1 ) != pathSeparator )
      {
         sbDirectoryName.insert( nLth++, pathSeparator );
      }

      return nLth;
   }

   public static String GetApplDirectoryFromView( TaskQualification qual, int lControl )
   {
      StringBuilder sbFileName = new StringBuilder();
      GetApplDirectoryFromView( sbFileName, qual, lControl, 256 );
      AppendPathSeparator( sbFileName );
      return sbFileName.toString();
   }

   protected static int GetApplDirectoryFromView( StringBuilder sbFileName, TaskQualification qual, int lControl, int lMaxLth )
   {
      Application app = qual.getApplication( );
      sbFileName.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.

      switch ( lControl )
      {
         case zAPPL_NAME:
            sbFileName.append( app.getName( ) );
            break;

         case zAPPL_DIR_LIB:
            throw new ZeidonException( "No longer supported" );

         case zAPPL_DIR_OBJECT:
            sbFileName.append( app.getObjectDir( ) );
            break;

         case zAPPL_DIR_LOCAL:
             throw new ZeidonException( "No longer supported" );

         case zAPPL_DIR_SHARED:
             throw new ZeidonException( "No longer supported" );

         case zAPPL_DIR_QLPLR:
             throw new ZeidonException( "No longer supported" );

         case zAPPL_DIR_SOURCE:
             throw new ZeidonException( "No longer supported" );

         default:
            throw new ZeidonException( "Unknown control value %d", lControl );
      }

      return 0;
   }

   protected static int GetApplDirectoryFromView( StringBuilder sbFileName, View view, int lControl, int lMaxLth )
   {
      return GetApplDirectoryFromView( sbFileName, view.getTask(), lControl, lMaxLth );
   }

   //  RETURNS:          0 - Hierarchical cursor position set
   //          zCALL_ERROR - Error in establishing hierarchical cursor
    protected int DefineHierarchicalCursor( View view, String entityName )
    {
        int nRC;
        EntityCursor cursor = view.cursor( entityName );
        nRC = 0;
        hierInstanceIterator = cursor.getChildrenHier( false ).iterator();
        hierInstanceEntityName = entityName;

        return nRC;
    }

    protected int GetEntityNameForHierarchicalCsr( int lLevel, StringBuilder sbEntityName, int lPos, View view )
    {
        sbEntityName.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
        sbEntityName.append( hierInstanceEntityName );
        return 0;
    }

   //  RETURNS:    0 - OK
   //              zCURSOR_UNDEFINED     - Entity cursor is undefined
   //              zCURSOR_NULL          - Entity cursor is null
   //              zCALL_ERROR
   protected int GetEntityNameForHierarchicalCsr( MutableInt miLevel, StringBuilder sbEntityName, MutableInt miPos, View view )
   {
      int nRC;
      sbEntityName.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      EntityCursor cursor = view.cursor( hierInstanceEntityName );
      if ( cursor.isNull() )
      {
         nRC = zCURSOR_NULL;
         miLevel.setValue( -1 );
      }
      else
      {
         nRC = 0;
         miLevel.setValue( cursor.getDepth( ) );
         sbEntityName.append( hierInstanceEntityName );
         miPos.setValue( 0 );
      }

      // TODO: DG???  miPos.setValue( view.cursor( hierInstanceEntityName ).getPosition( ) );
      return nRC;
   }

   //  RETURNS:
   //    zCURSOR_UNCHANGED          - Hierarchical cursor already positioned on last hierarchical position for view (UNCHANGED)
   //    zCURSOR_SET                - Hierarchical cursor positioned on next hierarchical entity
   //    zCURSOR_SET_NEWPARENT      - Hierarchical cursor positioned on next hierarchical entity - NEW PARENT
   //    zCURSOR_SET_RECURSIVECHILD - Hierarchical cursor positioned on next hierarchical entity RECURSIVECHILD
   //    zCALL_ERROR                - Error in call
   protected int
   SetCursorNextEntityHierarchical( int lLevel, StringBuilder sbEntityName, View view )
   {
      sbEntityName.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      if ( hierInstanceIterator == null )
      {
         return zCURSOR_UNCHANGED;
      }

      if ( ! hierInstanceIterator.hasNext() )
      {
         DropHierarchicalCursor( view ); // We'll drop it since it's no longer needed.
         return zCURSOR_UNCHANGED;
      }

      EntityInstance ei = hierInstanceIterator.next();
      hierInstanceEntityName = ei.getEntityDef().getName();
      int nRC = view.cursor( hierInstanceEntityName ).setCursor( ei ).toInt();
      sbEntityName.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      sbEntityName.append( hierInstanceEntityName );
      return nRC;
   }

   protected int SetCursorNextEntityHierarchical( MutableInt miLevel, StringBuilder sbEntityName, View view )
   {
      miLevel.setValue( 0 );
      sbEntityName.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      if ( hierInstanceIterator == null )
      {
         return zCURSOR_UNCHANGED;
      }

      if ( ! hierInstanceIterator.hasNext() )
      {
         DropHierarchicalCursor( view ); // We'll drop it since it's no longer needed.
         return zCURSOR_UNCHANGED;
      }

      EntityInstance ei = hierInstanceIterator.next();
      hierInstanceEntityName = ei.getEntityDef().getName();
      int nRC = view.cursor( hierInstanceEntityName ).setCursor( ei ).toInt();
      sbEntityName.append( hierInstanceEntityName );
      miLevel.setValue( view.cursor( hierInstanceEntityName ).getDepth( ) );
      return nRC;
   }

   protected int DropHierarchicalCursor( View view )
   {
      hierInstanceIterator = null;  // Allows GC to clean up the iterator.
      return 0;
   }

   public int SetSelectStateOfEntityForSet( View view, String entityName, int nState, int nSelectSet )
   {
       SelectSet selectSet = view.getSelectSet( nSelectSet );
       EntityCursor cursor = view.cursor( entityName );
       if ( nState == 0 )
       {
           // Is it off?
           if ( ! selectSet.isSelected( cursor ) )
               return 1;  // Yes.  Return 1 to indicate it was already off.

           selectSet.deselect( cursor );
           return 0;
       }

       // Is it on?
       if ( selectSet.isSelected( cursor ) )
           return 1;  // Yes.  Return 1 to indicate it was already on.

       selectSet.select( cursor );
       return 0;
   }

   private CursorResult findSelectedEntity( View view, EntityCursor cursor, CursorResult rc )
   {
      SelectSet selectSet = view.getSelectSet();
      while ( rc.isSet() && ! selectSet.isSelected( cursor ) )  // isSet ==> set, setNewParent, setRecursiveChild
      {
         rc = cursor.setNextContinue();
      }

      return rc;
   }

   //  RETURNS: zCURSOR_NULL      - No entity instances exist
   //           zCURSOR_UNCHANGED - Entity cursor unchanged
   //           zCURSOR_SET       - Entity position established
   //           zCALL_ERROR       - Error in call
   protected int SetCursorFirstSelectedEntity( View view, String entityName, String scopingEntity )
   {
      EntityCursor cursor = view.cursor( entityName );
      return findSelectedEntity( view, cursor, cursor.setFirst( scopingEntity ) ).toInt();
   }

   //  RETURNS: zCURSOR_NULL          - No entity instances exist
   //           zCURSOR_UNCHANGED     - Entity cursor unchanged
   //           zCURSOR_SET           - Entity position established
   //           zCURSOR_SET_NEWPARENT - Entity position changed within new parent
   //           zCALL_ERROR           - Error in call
   protected int SetCursorNextSelectedEntity( View view, String entityName, String scopingEntity )
   {
      EntityCursor cursor = view.cursor( entityName );
      return findSelectedEntity( view, cursor, cursor.setNextContinue() ).toInt();
   }

   //  RETURNS: 0           - Entity Instance has not been selected
   //           1           - Entity Instance has been selected
   //           zCALL_ERROR - Error in call
   protected int GetSelectStateOfEntity( View view, String entityName )
   {
      SelectSet selectSet = view.getSelectSet();
      EntityCursor cursor = view.cursor( entityName );
      return selectSet.isSelected( cursor ) ? 1 : 0;
   }

   //  RETURNS: 0           - Entity Instance has been successfully selected/deselected
   //           1           - Entity already selected/deselected
   //           zCALL_ERROR - Error excluding entity instance
   protected int SetSelectStateOfEntity( View view, String entityName, int selectState )
   {
      EntityCursor cursor = view.cursor( entityName );
      SelectSet selectSet = view.getSelectSet();
      if ( selectState == 1 )
      {
         if ( selectSet.isSelected( cursor ) )
         {
            return 1;
         }

         selectSet.select( cursor );
      }
      else
      {
         if ( ! selectSet.isSelected( cursor ) )
         {
            return 1;
         }

         selectSet.deselect( cursor );
      }

      return 0;
   }

   protected int SetAllSelectStatesForEntity( View view, String entityName, int selectState, String scopingEntity )
   {
      SelectSet selectSet = view.getSelectSet();

      view = view.newView(); // Create a copy so we can muck the cursors.
      EntityCursor cursor = view.cursor( entityName );

      for ( CursorResult rc = cursor.setFirst( scopingEntity );
            rc.isSet(); // isSet ==> set, setNewParent, setRecursiveChild
            rc = cursor.setNextContinue() )
      {
         if ( selectState == 1 )
         {
            selectSet.select( cursor );
         }
         else
         {
            selectSet.deselect( cursor );
         }
      }

      return 0;
   }

   protected int SetAllSelectStatesForEntity( View view, String entityName, int selectState, int scopingEntity )
   {
      if ( scopingEntity == zSCOPE_OI )
      {
         return SetAllSelectStatesForEntity( view, entityName, selectState, view.getLodDef( ).getRoot( ).getName( ) );
      }
      else
      {
         return SetAllSelectStatesForEntity( view, entityName, selectState, "" );
      }
   }

   //  RETURNS: >= 0                  - Absolute Entity number of returned ok
   //           zCURSOR_NULL          - Entity cursor is null
   protected long GetAbsolutePositionForEntity( MutableInt position, View view, String entityName )
   {
      long lRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.hasAny() == false )
      {
         lRC = zCURSOR_NULL;
      }
      else
      {
         lRC = cursor.getHierPosition( );
         position.setValue( lRC );
      }

      return lRC;
   }

   //  RETURNS: zCURSOR_NULL          - Entity cursor is null
   //           zCURSOR_SET           - Entity position changed within
   //                                   current parent
   //           zCALL_ERROR           - Error in call
   protected int SetCursorAbsolutePosition( StringBuilder sbReturnEntityName, View view, long position )
   {
      sbReturnEntityName.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      EntityInstance ei = view.getEntityByHierPosition( position );
      if ( ei == null )
      {
         return zCURSOR_UNCHANGED;
      }

      sbReturnEntityName.append( ei.getEntityDef().getName() );
      return view.cursor( sbReturnEntityName.toString() ).setCursor( ei ).toInt();
   }

   private int getTableEntry( StringBuilder sbTableValue,
                              View view,
                              String entityName,
                              String attributeName,
                              String contextName,
                              MutableInt index )
   {
      AttributeDef attributeDef = view.getLodDef().getEntityDef( entityName ).getAttribute( attributeName );
      TableDomain domain = (TableDomain) attributeDef.getDomain();
      List entries = domain.getTableEntries( view.getTask(), contextName );

      sbTableValue.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      if ( index.intValue() >= entries.size() )
      {
         return -1;
      }

      sbTableValue.append( entries.get( 0 ).toString() );
      return 0;
   }

   protected int GetFirstTableEntryForAttribute( StringBuilder sbTableValue,
                                                 View   view,
                                                 String entityName,
                                                 String attributeName,
                                                 String contextName,
                                                 MutableInt index )
   {
      index.setValue( 0 );
      return getTableEntry( sbTableValue, view, entityName, attributeName, contextName, index );
   }

   protected int GetNextTableEntryForAttribute( StringBuilder sbTableValue,
                                                View   view,
                                                String entityName,
                                                String attributeName,
                                                String contextName,
                                                MutableInt index )
   {
      index.setValue( index.intValue() + 1 );
      return getTableEntry( sbTableValue, view, entityName, attributeName, contextName, index );
   }

   protected int zGetFirstEntityNameForView( View view, StringBuilder sbEntityName )
   {
      LodDef lodDef = view.getLodDef();
      EntityDef entityDef = lodDef.getRoot();
      sbEntityName.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      sbEntityName.append( entityDef.getName() );
      return 0;
   }

   protected int zGetNextEntityNameForView( View view, StringBuilder sbEntityName )
   {
      LodDef lodDef = view.getLodDef();
      EntityDef entityDef = lodDef.getEntityDef( sbEntityName.toString() );
      entityDef = entityDef.getNextHier();
      if ( entityDef == null )
         return -1;

      sbEntityName.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      sbEntityName.append( entityDef.getName() );
      return 0;
   }

   protected int zGetFirstAttributeNameForEntity( View view, String entityName, StringBuilder sbAttribName )
   {
      EntityDef entityDef = view.getLodDef().getEntityDef( entityName );
      AttributeDef AttributeDef = entityDef.getAttribute( 0 );
      if ( AttributeDef == null )
          return -1;

      if ( AttributeDef.isHidden() )
     	  return  -1;
      //if ( sbAttribName != null ) // Do we need this?
      sbAttribName.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      sbAttribName.append( AttributeDef.getName() );
      return 0;
   }

   protected int zGetNextAttributeNameForEntity( View view, String entityName, StringBuilder sbAttribName )
   {
      EntityDef entityDef = view.getLodDef().getEntityDef( entityName );
      AttributeDef AttributeDef = entityDef.getAttribute( sbAttribName.toString() );
      AttributeDef = AttributeDef.getNextAttributeDef();
      if ( AttributeDef == null )
         return -1;

      if ( AttributeDef.isHidden() )
    	  return  -1;

      sbAttribName.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      sbAttribName.append( AttributeDef.getName() );
      return 0;
   }

   //./ ADD NAME=ObjectInstanceUpdatedFromFile
   // Source Module=kzoeoiaa.c
   /////////////////////////////////////////////////////////////////////////////
   //
   //  ENTRY:      ObjectInstanceUpdatedFile
   //
   //  PURPOSE:    To determine if an Object instance has been updated since
   //              it was last activated/committed from/to a portable file.
   //
   //  PARAMETERS: lpView - View of object instance to check.
   //
   //  RETURNS:    0           - Instance has not been updated
   //              1           - Instance has been updated
   //              zCALL_ERROR - Error in call
   //
   /////////////////////////////////////////////////////////////////////////////
   public int
   ObjectInstanceUpdatedFromFile( View  lpView )
   {
   // LPVIEWCSR     lpViewCsr;
   // LPVIEWOI      lpViewOI;
      int           nRC = 0;

   // lpViewCsr = zGETPTR( lpView->hViewCsr );
   // lpViewOI  = zGETPTR( lpViewCsr->hViewOI );
   // nRC       = lpViewOI->bUpdatedFile;

      return( nRC );
   }

   static final char Encrypt1[] = { 22, 5, 13, 16, 15, 0, 6, 23, 2, 19, 12, 9, 10,
                                     1, 25, 4, 17, 7, 18, 11, 21, 14, 24, 20, 3, 8, 0 };

   static final char Encrypt2[] = { 10, 17, 4, 22, 1, 6, 20, 13, 12, 19, 5, 24, 8,
                                    15, 7, 23, 2, 11, 21, 9, 14, 0, 25, 3, 16, 18, 0 };

   static final char EncryptNonAlpha[] = {  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                       '\"',    // ' '
                                       '@',     // '\"'
                                       '%',     // '!'
                                       '4',     // '#'
                                       '&',     // '$'
                                       '$',     // '%'
                                       '\'',    // '&'
                                       '3',     // '\''
                                       '[',     // '('
                                       '(',     // ')'
                                       ':',     // '*'
                                       '5',     // '+'
                                       '+',     // ','
                                       '!',     // '-'
                                       '#',     // '.'
                                       '?',     // '/'
                                       '|',     // '0'
                                       '.',     // '1'
                                       '/',     // '2'
                                       '`',     // '3'
                                       '6',     // '4'
                                       ',',     // '5'
                                       '7',     // '6'
                                       '-',     // '7'
                                       '9',     // '8'
                                       '8',     // '9'
                                       '*',     // ':'
                                       '1',     // ';'
                                       ';',     // '<'
                                       '>',     // '='
                                       '<',     // '>'
                                       ')',     // '?'
                                       ' ',     // '@'
                                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                       0, 0, 0, 0, 0, 0,
                                       '}',     // '['
                                       '=',     // '\\'
                                       '2',     // ']'
                                       '{',     // '^'
                                       '\\',    // '_'
                                       ']',     // '`'
                                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                       0, 0, 0, 0, 0, 0,
                                       '^',     // '{'
                                       '_',     // '|'
                                       '~',     // '}'
                                       '0'  };  // '~'

  /**
    * This should really be named "UfObfuscateString" because it doesn't encrypt the string,
    * just makes it harder to read it in an .ini file.
    *
    * Logic copied directly from kzoeufaa.c
    *
    * @param sbEncryptedString
    * @param originalString
    * @param length
    */
   public static final int UfEncryptString( StringBuilder sbEncryptedString, String originalString, int length )
   {
      sbEncryptedString.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      int uLth = originalString.length();
      //        if ( uLth > 26 )
      //            uLth = 26;

      char[] pchOut = new char[ uLth + 1 ];
      char[] pchIn = originalString.toCharArray();

      char uChar = 0;
      int nOrderIdx = 0;
      boolean bNullFound = false;
      pchOut[ uLth ] = 0;
      while ( Encrypt2[ nOrderIdx ] > (uLth - 1) )
      {
          nOrderIdx++;
      }

      int nInLth = pchIn.length;
      while ( nInLth > uLth || nInLth > 25 )
      {
          nInLth -= uLth;
      }

      char cChar = 0;

      pchOut[ Encrypt2[ nOrderIdx ] ] = Encrypt1[ nInLth ];
      nOrderIdx++;
      while ( uChar < (uLth - 1) )
      {
          while ( Encrypt2[ nOrderIdx ] > (uLth - 1) )
          {
              nOrderIdx++;
          }

          if ( ! bNullFound && pchIn[ uChar ] > 0 )
          {
              cChar = pchIn[ uChar ];

              if ( Character.isLetter( cChar ) )
              {
                  while ( cChar >= 'a' )
                  {
                      cChar -= ' ';
                  }

                  while ( cChar < 'A' )
                  {
                      cChar += 11;
                  }

                  cChar -= 'A';
                  if ( uChar % 2 > 0 )
                  {
                      pchOut[ Encrypt2[ nOrderIdx ] ] = Encrypt1[ cChar ];
                  }
                  else
                  {
                      pchOut[ Encrypt2[ nOrderIdx ] ] = Encrypt2[ cChar ];
                  }
              }
              else
              {
                  pchOut[ Encrypt2[ nOrderIdx ] ] = (char) ( EncryptNonAlpha[ cChar ] - 'a' );
              }
          }
          else
          {
              cChar += 17;
              if ( cChar > 25 )
              {
                  cChar -= 25;
              }

              bNullFound = true;
              if ( uChar % 2 > 0 )
              {
                  pchOut[ Encrypt2[ nOrderIdx ] ] = Encrypt2[ cChar ];
              }
              else
              {
                  pchOut[ Encrypt2[ nOrderIdx ] ] = Encrypt1[ cChar ];
              }
          }

          uChar++;
          nOrderIdx++;
      }

      for ( uChar = 0 ; uChar < uLth ; uChar++ )
      {
          pchOut[ uChar ] += 'a';
      }

      sbEncryptedString.append( pchOut );
      return sbEncryptedString.length( );
   }

   public static final String UfEncryptString( String encryptedString, String originalString, int length )
   {
      StringBuilder sb = new StringBuilder( originalString );
      UfEncryptString( sb, originalString, length );
      return sb.toString( );
   }

   public static final int UfDecryptString( StringBuilder sbDecryptedString, String original, int length )
   {
      sbDecryptedString.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      if ( original.length() == 0 )
      {
         return( 0 );
      }

      int uLth = original.length();
//    if ( uLth > 26 )
//       uLth = 26;

      char[] pchIn = original.toCharArray();
      char[] pchOut = new char[ length + 1 ];
      char uChar = 0;
      int nOrderIdx = 0;
      while ( Encrypt2[ nOrderIdx ] > (uLth - 1) )
      {
         nOrderIdx++;
      }

      int cReturnLth = pchIn[ Encrypt2[ nOrderIdx ] ] - 'a';
      int nReturnLth = 0;
      while ( Encrypt1[ nReturnLth ] != cReturnLth )
      {
         nReturnLth++;
      }

      cReturnLth = nReturnLth;
      nOrderIdx++;
      while ( cReturnLth > 0 )
      {
         while ( Encrypt2[ nOrderIdx ] > (uLth - 1) )
         {
            nOrderIdx++;
         }

         char ucChar = pchIn[ Encrypt2[ nOrderIdx ] ];
         if ( Character.isLetter( ucChar ) )
         {
            ucChar -= 'a';
            if ( uChar % 2 > 0 )
            {
               int cWk = 0;
               while ( Encrypt1[ cWk ] != ucChar )
               {
                  cWk++;
               }

               pchOut[ uChar ] = (char) (cWk + 'a');
            }
            else
            {
               int cWk = 0;
               while ( Encrypt2[ cWk ] != ucChar )
               {
                  cWk++;
               }

               pchOut[ uChar ] = (char) ( cWk + 'a' );
            }
         }
         else
         {
            int nIdx;

            // Look for the encrypted char in the non-alpha table.
            for ( nIdx = 32; nIdx < 127; nIdx++ )
            {
               if ( EncryptNonAlpha[ nIdx ] == ucChar )
               {
                  break;
               }
            }

            if ( nIdx == 127 )
            {
               SysMessageBox( null, "Zeidon Internal Error", "Error decrypting string", 0 );
               return( zCALL_ERROR );
            }

            pchOut[ uChar ] = (char) nIdx;
         }

         cReturnLth--;
         uChar++;
         nOrderIdx++;
      }

      pchOut[ uChar ] = 0;
      sbDecryptedString.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      sbDecryptedString.append( pchOut );
      return( nReturnLth );
   }

   protected static final int Minute =       1;
   protected static final int Hour =         (Minute * 60);
   protected static final int Day =          (Hour * 24);
   protected static final int Week =         (Day * 7);
   protected static final int Year =         (Day * 365);
   protected static final int LeapYear =     (Day * 366);
   protected static final int Century =      ((Year * 76) + (LeapYear * 24));
   protected static final int LeapCentury =  ((Year * 75) + (LeapYear * 25));
   protected static final int Year1900 =     ((Century * 14) + (LeapCentury * 5));
   protected static final int Year2000 =     ((Century * 15) + (LeapCentury * 5));
   protected static final int lNullInteger = -2147483647 - 1;
   protected static final                     // J  F  M  A  M  J  J  A  S  O  N  D
                          char cMonth_Val[ ] = { 6, 2, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };

   protected static final int usDayTable[ ] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
   protected static final int usLeapDayTable[ ] = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };

   // Internal DateTime structure
   public static class DateTimeRecord
   {
      private long ulDateMinutes;    // Minutes since year zero
      private int  usTSeconds;       // Thousandths of seconds
   };


   //./ ADD NAME=UfDateTimeDiff
   // Source Module=kzoeufaa.c
   /////////////////////////////////////////////////////////////////////////////
   //
   // ENTRY:      UfDateTimeDiff
   //
   // PARAMETERS:
   //             plDiff      - pointer to variable returning difference
   //             lpDateTime1 - First Timestamp
   //             lpDateTime2 - Second Timestamp
   //             nDiffType   - unit for difference (zDT_SECOND, ...)
   //
   // RETURNS:     0 - Success
   //             -1 - overflow
   //    zCALL_ERROR - error during call (invalid AmountType)
   //
   /////////////////////////////////////////////////////////////////////////////
   //./ END + 4
   public int
   UfDateTimeDiff( int  lDiff,
                   DateTimeRecord   lpDateTime1,
                   DateTimeRecord   lpDateTime2,
                   int  nDiffType )
   {
   /*****
      int             nRC = 0;
      int             usDiffLo;
      int             ulDiffHi;
      int             lY1, lY2, lM1, lM2, lD1, lD2;
      DateTimeRecord  lpDT1, lpDT2;
      DateTimeRecord  dt, dt1, dt2;
      boolean         bNegative;
      boolean         bOverflow = false;

      lDiff = 0;

   // memcpy( dt1, lpDateTime1, sizeof(DateTimeInternalRecord) );
   // memcpy( dt2, lpDateTime2, sizeof(DateTimeInternalRecord) );
      lpDT1 = dt1;
      lpDT2 = dt2;

      // For Year, Month or Date
      if ( nDiffType == zDT_YEAR ||
           nDiffType == zDT_MONTH ||
           nDiffType == zDT_DAY )
      {
        // use only the date part of the timestamp
        lpDT1.usTSeconds = 0;
        lpDT2.usTSeconds = 0;
        ulDiffHi = lpDT1.ulDateMinutes % Day;
        lpDT1.ulDateMinutes -= ulDiffHi;
        ulDiffHi = lpDT2.ulDateMinutes % Day;
        lpDT2.ulDateMinutes -= ulDiffHi;
      }

      // determine the sign of the difference
      nRC = fnCompareDateTimeToDateTime( &dt1, &dt2 );
      bNegative = (nRC > 0);

      // shortcut for equal values.
      if ( nRC == 0 )
         return( 0 );

      // If negative, exchange the two date time values.
      if ( bNegative )
      {
        lpDT1 = &dt2;
        lpDT2 = &dt1;
      }

      // calculate the difference with carry bit
      ulDiffHi = lpDT2.ulDateMinutes - lpDT1.ulDateMinutes;
      if ( lpDT1.usTSeconds > lpDT2.usTSeconds )
      {
        ulDiffHi--;
        usDiffLo = (int) (lpDT2.usTSeconds - lpDT1.usTSeconds + 60000);
      }
      else
      {
        usDiffLo = lpDT2.usTSeconds - lpDT1.usTSeconds;
      }

      switch ( nDiffType )
      {
         case zDT_YEAR:
            // calculate the difference of the year number
            lY1 = fnGetDateTimeComponent( (LPDATETIME)lpDT1, zDT_YEAR );
            lY2 = fnGetDateTimeComponent( (LPDATETIME)lpDT2, zDT_YEAR );
            lDiff = lY2 - lY1;

            // check for carry (e.g. "19970101" - "19961231" has lDiff=1
            // and has to be corrected!)
            UfAddToDateTime( (LPDATETIME)lpDT1, lDiff, zDT_YEAR);
            if ( fnCompareDateTimeToDateTime( lpDT1, lpDT2 ) == 1 )
            {
              lDiff--;
            }

            break;

         case zDT_MONTH:
            // get the days for additional carry, then set it 0 for calculation
            lD1 = fnGetDateTimeComponent( (LPDATETIME)lpDT1, zDT_DAY );
            lD2 = fnGetDateTimeComponent( (LPDATETIME)lpDT2, zDT_DAY );
            fnSetDateTimeComponent( (LPDATETIME)lpDT1, zDT_DAY, 0L );
            fnSetDateTimeComponent( (LPDATETIME)lpDT2, zDT_DAY, 0L );

            // calculate the difference of the years and the months
            lY1 = fnGetDateTimeComponent( (LPDATETIME)lpDT1, zDT_YEAR );
            lY2 = fnGetDateTimeComponent( (LPDATETIME)lpDT2, zDT_YEAR );
            lM1 = fnGetDateTimeComponent( (LPDATETIME)lpDT1, zDT_MONTH );
            lM2 = fnGetDateTimeComponent( (LPDATETIME)lpDT2, zDT_MONTH );
            lDiff = (lY2 - lY1) * 12 + lM2 - lM1;

            // check for carry caused by leap year (has to be corrected!)
            do
            {
              memcpy( &dt, lpDT1, sizeof(DateTimeInternalRecord) );
              UfAddToDateTime( (LPDATETIME)&dt, lDiff, zDT_MONTH);
              nRC = fnCompareDateTimeToDateTime( &dt, lpDT2 );

              lDiff += nRC;

            } while ( nRC );

            // check for carry caused by difference in days (and correct it)
            if ( lD2 < lD1 )
              lDiff--;

            break;

         case zDT_DAY:
            lDiff = (int) (ulDiffHi / Day);
            break;

         case zDT_HOUR:
            lDiff = (int) (ulDiffHi / Hour);
            break;

         case zDT_MINUTE:
            if (ulDiffHi > 0x7fffffff)
            {
              bOverflow = true;
              break;
            }

            lDiff = (int) ulDiffHi;
            break;

         case zDT_SECOND:
            if (ulDiffHi > (0x7fffffff / 60 - 1) )
            {
              bOverflow = true;
              break;
            }

            lDiff = (int) (ulDiffHi * 60 + usDiffLo / 1000);
            break;

         default:
            // "KZOEE023 - Invalid parameter, "
            fnSysMessageBox( 0, "Zeidon Error", "Invalid parameter", 0 );
         // fnIssueCoreError( null, lpView, 8, 23, 0, "nDiffType", "" );
         // fnOperationReturn( iUfAddToDateTime, lpCurrentTask );
            return( zCALL_ERROR );
      }

      if ( bOverflow )
      {
      // fnOperationReturn( iUfAddToDateTime, lpCurrentTask );
         return( -1 );
      }

      if ( bNegative )
        lDiff *= -1;
   ***/
      return( lDiff );

   } // UfDateTimeDiff


   // Source Module=kzoeufaa.c
   /////////////////////////////////////////////////////////////////////////////
   //
   // FUNCTION:   UfStringToDateTime
   //
   // PARAMETERS: lpDateTime       - pointer to the DateTime data
   //              cpcDateTimeString - a date-time string (YYYYMMDDHHmmSSTht)
   //                                 contains one of the following formats:
   //                                    YYYYMMDDHHmmSSTht
   //                                    YYYYMMDDHHmmSSTh
   //                                    YYYYMMDDHHmmSST
   //                                    YYYYMMDDHHmmSS
   //                                    YYYYMMDDHHmm
   //                                    YYYYMMDD
   //
   //                                        YYYY - year
   //                                        MM   - month
   //                                        DD   - day
   //                                        HH   - hour
   //                                        mm   - minute
   //                                        ss   - seconds
   //                                        T    - tenths of seconds
   //                                        h    - hundredths of seconds
   //                                        t    - thousandths of seconds
   //
   // PURPOSE:    To convert a string to a DateTime (T) attribute type
   //              The string is checked for correct values (e.g. 19960100
   //              results in zCALL_ERROR, but 00000000112233 is valid,
   //              because this is just a time).
   //
   // RETURNS:    0 - String converted, info set in DateTime area
   //    zCALL_ERROR - Error in call
   //
   /////////////////////////////////////////////////////////////////////////////
   //./ END + 2
   public int
   UfStringToDateTime( String cpcDateTimeString, DateTimeRecord lpDateTime )
   {
      int           usStringLth;
      int           usMonth;
      int           usDay;
      int           usDayOrg;
      int           usSeconds;
      int           usTSeconds;
      int           ulYear;
      int           ulHours;
      int           usMinutes;
      int           ulDateMinutes;
      int           ulDays;
      int           ulWorkYear;
      StringBuilder sbWorkString = new StringBuilder( 20 );
      DateTimeRecord lpDTInternal;
      boolean       bDateSet;
      int           nRC = 0;

      lpDTInternal = lpDateTime;

      // Null string will set the DateTime to 'NULL'
      if ( StringUtils.isBlank( cpcDateTimeString ) )
      {
         lpDTInternal.ulDateMinutes = lNullInteger;
         lpDTInternal.usTSeconds = 0;
         return( 0 );
      }

      usMonth = 0;
      usDay = 0;
      ulYear = 0;
      ulHours = 0;
      usMinutes = 0;
      usSeconds = 0;
      usTSeconds = 0;

      usStringLth = zstrlen( cpcDateTimeString );
      switch ( usStringLth )
      {
         case 17:   // YYYYMMDDHHmmSSTht
         case 16:   // YYYYMMDDHHmmSSTh
         case 15:   // YYYYMMDDHHmmSST
            // Get Thousandths of seconds Value
            zstrcpy( sbWorkString, cpcDateTimeString.substring( 14 ) );
            usTSeconds = zatol( sbWorkString.toString( ) );
            if ( usStringLth < 17 )
            {
               usTSeconds *= (usStringLth == 16) ? 10 : 100 ;
            }

         case 14:   // YYYYMMDDHHmmSS
            // Get Seconds Value
            sbWorkString.insert( 0, cpcDateTimeString.charAt( 12 ) );
            sbWorkString.insert( 1, cpcDateTimeString.charAt( 13 ) );
            sbWorkString.insert( 2, '\0' );
            usSeconds = zatol( sbWorkString.toString( ) );
            if ( usSeconds > 59 )
            {
               usSeconds = 59;
               nRC = zCALL_ERROR;
            }

         case 12:   // YYYYMMDDHHmm
            // Get Minutes Value
            sbWorkString.insert( 0, cpcDateTimeString.charAt( 10 ) );
            sbWorkString.insert( 1, cpcDateTimeString.charAt( 11 ) );
            sbWorkString.insert( 2, '\0' );
            usMinutes = zatol( sbWorkString.toString( ) );
            if ( usMinutes > 59 )
            {
               usMinutes = 59;
               nRC = zCALL_ERROR;
            }

            // Get Hours Value
            sbWorkString.insert( 0, cpcDateTimeString.charAt( 8 ) );
            sbWorkString.insert( 1, cpcDateTimeString.charAt( 9 ) );
            sbWorkString.insert( 2, '\0' );
            ulHours = zatol( sbWorkString.toString( ) );
            if ( ulHours > 23 )
            {
               ulHours = 23;
               nRC = zCALL_ERROR;
            }

         case 8:    // YYYYMMDD
            // Get Day Value
            sbWorkString.insert( 0, cpcDateTimeString.charAt( 6 ) );
            sbWorkString.insert( 1, cpcDateTimeString.charAt( 7 ) );
            usDay = zatol( sbWorkString.toString( ) );

            // Get Month Value
            sbWorkString.setLength(0);
            sbWorkString.insert( 0, cpcDateTimeString.charAt( 4 ) );
            sbWorkString.insert( 1, cpcDateTimeString.charAt( 5 ) );
            usMonth = zatol( sbWorkString.toString( ) );

            // Get Year Value
            zstrncpy( sbWorkString, cpcDateTimeString, 4 );
            ulYear = zatol( sbWorkString.toString( ) );

            // Check to see if we have date/datetime or only time without date.
            bDateSet = (ulYear != 0 || usMonth != 0 || usDay != 0);

            if ( ulYear == 0 )
            {
              ulYear = 1900;
              if ( bDateSet )
              {
                nRC = zCALL_ERROR;
              }
            }
            // the year will be multiplied with minutes/year and then stored as
            // unsigned long. These means, max. can be not much more than 8000
            if ( ulYear > 8000 )
            {
              ulYear = 8000;
              nRC = zCALL_ERROR;
            }

            // if month out of range, make it January
            if ( usMonth < 1 || usMonth > 12 )
            {
               usMonth = 1;
               if ( bDateSet )
               {
                  nRC = zCALL_ERROR;
               }
            }

            // Get valid day for the month
            usDayOrg = usDay;
            usDay = fnValidateDay( usMonth, usDayOrg, ulYear );
            if ( usDay != usDayOrg )
            {
               if ( bDateSet )
               {
                  nRC = zCALL_ERROR;
               }
            }

            break;

         default:
            return( zCALL_ERROR );
      }

      /* Calculate Year in Minutes */
      ulWorkYear = 0;
      ulDateMinutes = 0;

      // Fast path for dates starting Jan 1, 1900.
      // Start point set to beginning of century.
      if ( ulYear >= 1900L )
      {
         ulWorkYear = 1900;
         ulDateMinutes = Year1900;
         if ( ulYear >= 2000L )
         {
            ulWorkYear = 2000;
            ulDateMinutes += Century;
         }
      }

      // This will get us to Jan 1, of the desired year.
      // This will take a bit longer when the year is less than 1900.
      while ( ulWorkYear < ulYear )
      {
         if ( (ulWorkYear % 4) == 0 &&
              ((ulWorkYear % 100) != 0 || (ulWorkYear % 400) == 0) )
         {
            ulDateMinutes += LeapYear;
         }
         else
         {
            ulDateMinutes += Year;
         }

         ulWorkYear++;
      }

      // This will get the number of days from the Jan 1,
      // to the beginning of the desired month.
      if ( (ulWorkYear % 4) == 0 &&
           ((ulWorkYear % 100) == 0 || (ulWorkYear % 400) == 0) )
      {
         ulDays = usLeapDayTable[ usMonth - 1 ];
      }
      else
      {
         ulDays = usDayTable[ usMonth - 1 ];
      }

      ulDays += usDay - 1;                 // add day of the month, for days
                                           // this year
      ulDateMinutes += ulDays * Day;       // add days_minutes to total minutes
      ulDateMinutes += ulHours * Hour;     // add hours_minutes to total minutes
      // add minutes to total minutes
      ulDateMinutes += (usMinutes * Minute);

      // Now save this, before we forget...
      lpDTInternal.ulDateMinutes = ulDateMinutes;

      // Convert seconds to thousandths, and save it too.
      lpDTInternal.usTSeconds = usTSeconds + (usSeconds * 1000);

      return( nRC );

   }  /* END of StringToDateTime */

   private int
   fnValidateDay( int usMonth, int usDay, int ulYear )
   {
      int   usMax;

      if ( usDay >= 1 && usDay <= 28 )
      {
         return( usDay );
      }

      if ( usDay < 1 )
      {
         return( 1 );
      }

      switch ( usMonth )
      {
         case 2:
            usMax = 28;
            if ( (ulYear % 4) == 0 &&
                 ((ulYear % 100) != 0 || (ulYear % 400) == 0) )
            {
               usMax = 29;
            }

            break;

         case 4:
         case 6:
         case 9:
         case 11:
            usMax = 30;
            break;

         default:
            usMax = 31;
      }

      if ( usDay > usMax )
      {
         return( usMax );
      }
      else
      {
         return( usDay );
      }

   } /*** END fnValidateDay ***/

   // Signed long to Asciiz right justified (with leading zeros) for length
   // INPUT: Long value to be converted to Ascii string
   //         Ascii string address at which to set converted string
   //         Return string length - not including null terminator
   //
   private int
   zltoal( int    lValue,
           StringBuilder sb,
           int    nOffset,
           int    nLth )
   {
      String szTemp = null;
      int    nPos;
      int    k;

      szTemp = zltoa( lValue, szTemp );
      k = zstrlen( szTemp );
      if ( k < nLth )
      {
         nPos = nLth - k;
         zmemset( sb, nOffset, '0', nPos );
      }
      else
      {
         nPos = 0;
         k = nLth;
      }

      zstrncpy( sb, nPos + nOffset, szTemp, k );
      sb.insert( nLth + nOffset, '\0' );
      return nLth + nOffset;
   }

   //./ ADD NAME=UfDateTimeToString
   // Source Module=kzoeufaa.c
   /////////////////////////////////////////////////////////////////////////////
   //
   // FUNCTION:   UfDateTimeToString
   //
   // PARAMETERS: lpDateTime       - pointer to the DateTime data
   //              pchReturnString  - pointer to area to return string
   //              nMaxLth          - length of pchReturnString (including
   //                                 null terminator.)
   //
   // PURPOSE:    To convert a DateTime (T) attribute type into a string.
   //              If the DateTime attribute is 'NULL', a null string will
   //              be returned.
   //
   // RETURNS:    0 - String returned.
   //             -1 - Null string returned.
   //
   //           When nMaxLth is     format of returned string is
   //
   //                    9           YYYYMMDD
   //                    13          YYYYMMDDHHmm
   //                    15          YYYYMMDDHHmmSS
   //                    16          YYYYMMDDHHmmSST
   //                    17          YYYYMMDDHHmmSSTh
   //                    18          YYYYMMDDHHmmSSTht
   //
   //
   //                               (YYYYMMDDHHmmSSTht)
   //                                MM   - month
   //                                DD   - day
   //                                HH   - hour
   //                                mm   - minute
   //                                SS   - seconds
   //                                T    - tenths of seconds
   //                                h    - hundredths of seconds
   //                                t    - thousandths of seconds
   //
   //    zCALL_ERROR - Error in call
   //
   /////////////////////////////////////////////////////////////////////////////
   //./ END + 3
   public String
   UfDateTimeToString( DateTimeRecord lpDateTime, String pchReturnString, int nMaxLth )
   {
      StringBuilder sb = new StringBuilder( 20 );
      long       ulDateMinutes;
      int        k;
      int        usYear, usMonth, usDay, usHour, usMinute;
      int        usSeconds, usTSeconds;
      DateTimeRecord lpDTInternal;

      lpDTInternal = lpDateTime;

      if ( lpDTInternal.ulDateMinutes == lNullInteger )
      {
         pchReturnString = "";
         return pchReturnString;
      }

      if ( nMaxLth < 9 )
      {
         return null;
      }
      else
      if ( nMaxLth < 13 )
      {
         nMaxLth = 9;      // Let's assume 9.
      }
      else
      if ( nMaxLth < 15 )
      {
         nMaxLth = 13;     // Let's assume 13.
      }

      ulDateMinutes = lpDTInternal.ulDateMinutes;
      usTSeconds = lpDTInternal.usTSeconds;

      if ( ulDateMinutes >= Year2000 )
      {
         usYear = 2000;
         ulDateMinutes -= Year2000;
      }
      else
      if ( ulDateMinutes >= Year1900 )
      {
         usYear = 1900;
         ulDateMinutes -= Year1900;
      }
      else
      {
         usYear = 0;
      }

      for ( ; ; )
      {
         if ( (usYear % 4) == 0 &&
               ((usYear % 100) != 0 || (usYear % 400) == 0) )
         {
            if ( ulDateMinutes >= LeapYear )
            {
               usYear++;
               ulDateMinutes -= LeapYear;
            }
            else
            {
               break;
            }
         }
         else
         {
            if ( ulDateMinutes >= Year )
            {
               usYear++;
               ulDateMinutes -= Year;
            }
            else
            {
               break;
            }
         }
      }

      usDay = (int) (ulDateMinutes / Day);
      ulDateMinutes %= Day;

      k = 1;
      if ( (usYear % 4) == 0 &&
           ((usYear % 100) != 0 || (usYear % 400) == 0) )
      {
         while ( k < 12 && usDay >= usLeapDayTable[ k ] )
         {
            k++;
         }

         usMonth = k;
         if ( k == 12 || usDay <= usLeapDayTable[ k ] )
         {
            k--;
         }

         usDay -= usLeapDayTable[ k ];
      }
      else
      {
         while ( k < 12 && usDay >= usDayTable[ k ] )
         {
            k++;
         }

         usMonth = k;
         if ( k == 12 || usDay <= usDayTable[ k ] )
         {
            k--;
         }

         usDay -= usDayTable[ k ];
      }

      usDay++;
      usHour = (int) (ulDateMinutes / Hour) ;
      usMinute = (int) (ulDateMinutes % Hour );
      if ( usTSeconds != 0 )
      {
         usSeconds = usTSeconds / 1000;
         usTSeconds %= 1000;
      }
      else
      {
         usSeconds = 0;
      }

      zltoal( usYear, sb, 0, 4 );          // year to string
      zltoal( usMonth, sb, 4, 2 );     // month to string
      zltoal( usDay, sb,  6, 2 );       // day to string
      if ( nMaxLth == 9 )
      {
         return sb.toString( );
      }

      zltoal( usHour, sb,  8, 2 );      // hour to string
      zltoal( usMinute, sb, 10, 2 );   // minute to string
      if ( nMaxLth == 13 )
      {
         return sb.toString( );
      }

      zltoal( usSeconds, sb, 12, 2 );  // seconds to string
      if ( nMaxLth == 15 )
      {
         return sb.toString( );
      }

      // milliseconds to string
      zltoal( usTSeconds, sb, 14, (((nMaxLth - 15 ) > 3) ? 3 : (nMaxLth - 15)));

      return sb.toString( );

   }  /* END of DateTimeToString */

   protected int WebReturnToHomePage( View viewXfer, View view )
   {
      // TODO This should be somewhere else.
      return 0;
   }

   protected void ActivateDynamicDomain( View view, String string )
   {
     // TODO This should be somewhere else.
   }


   protected String GetRegistryCLSID( String stringCLSID, String string )
   {
      // TODO This should be somewhere else.
      return stringCLSID;
   }

   protected String GetRegistryPrintValue( String string, String string2,
                                           String stringCLSID, int regSz, String stringReturn, int i )
   {
      // TODO This should be somewhere else.
      return string;
   }

   protected String GetRegistryGeneralValue( String string, String string2,
                                             String stringCLSID, int regSz, String stringReturn, int i )
   {
      // TODO This should be somewhere else.
      return string;
   }

/* These are in ZGLOBAL1
   public int GetEntityNameFromStructure( String stringInternalEntityStructure, StringBuilder sbReturnEntityName )
   {
      sbReturnEntityName.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      sbReturnEntityName.append( stringInternalEntityStructure );
      return 0;
   }

   public String GetEntityNameFromStructure( String stringInternalEntityStructure, String returnEntityName )
   {
   // returnEntityName = stringInternalEntityStructure;
   // return returnEntityName;
      return stringInternalEntityStructure;
   }
*/

   /**
    * The C version of this method converts internalEntityStructure to an LPVIEWATTRIB and
    * compares attributeName to lpAttributeDef.szName.  In Java we don't pass the internal
    * value, just the name of the attribute, so we just do a simple compare here.
    *
    * @param attributeName
    * @param stringInternalEntityStructure
    * @return
    */
   protected int IsValidAttribute( String attributeName, String stringInternalEntityStructure )
   {
      int nRC = attributeName.equalsIgnoreCase( stringInternalEntityStructure ) ? TRUE : FALSE;
      return nRC;
   }

   //@override
   protected int IsValidAttribute( View view, String attributeName, String entityName )
   {
         EntityCursor cursor = null;

	      try{
	         cursor = view.cursor( entityName );
          }
          catch ( UnknownEntityDefException e )
          {
             return -1;
          }
          try{
 	         AttributeInstance attr = cursor.getAttribute( attributeName );
 	         if ( attr.getAttributeDef().isHidden() )
 	        	 return -1;
          }
          catch  ( UnknownAttributeDefException e )
          {
 	         return -1;

          }
      return 0;
   }

   //  RETURNS:    zCURSOR_... - Entity removed, and this is the status for setting the cursor.
   //                            These return codes are shown under the operations for SetCursor...Entity.
   //              zCALL_ERROR - Error removing entity instance
   protected int DropEntity( View view, String entityName, int pos )
   {
      int nRC;
      EntityCursor cursor = view.cursor( entityName );
      if ( cursor.isNull() )
      {
         nRC = zCALL_ERROR;
      }
      else
      {
         nRC = view.cursor(entityName).dropEntity( CURSOR_POS.get( pos ) ).toInt();
      }

      return nRC;
   }

   protected int zRTrim( String stringT, StringBuilder sbReturnString, int maxLth )
   {
      // remove trailing whitespace
      sbReturnString.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      sbReturnString.append( stringT.replaceAll( "\\s+$", "" ) );
      return sbReturnString.length( );
   }

   protected int zLTrim( String stringT, StringBuilder sbReturnString, int maxLth )
   {
      // remove leading whitespace
      sbReturnString.setLength( 0 ); // Use sb.setLength( 0 ); to clear a string buffer.
      sbReturnString.append( stringT.replaceAll( "^\\s+", "" ) );
      return sbReturnString.length( );
   }

   protected String zExpungeAllSubstring( String string, String subString )
   {
      int nLth = subString.length( );
      int k;
      if ( nLth > 0 )
      {
         StringBuilder sb = new StringBuilder( string );
         nLth--;
         while ( (k = sb.indexOf( subString )) >= 0 )
         {
            sb.replace( k, k + nLth, "" );
         }

         string = sb.toString( );
      }

      return string;
   }

   protected String zReplaceSubString( String string, int nPosStart, int nPosEnd, String replaceString )
   {
      StringBuilder sb = new StringBuilder( string );
      sb.replace( nPosStart, nPosEnd, replaceString );
      return sb.toString( );
   }

   protected int zReplaceSubString( StringBuilder sb, int nPosStart, int nPosEnd, String replaceString )
   {
      sb.replace( nPosStart, nPosEnd, replaceString );
      return sb.length( );
   }

   protected int ExecuteQueryForContactList( View queryView )
   {
      // TODO - Create Code.
      return 0;
   }

   public void RefreshWindow( View view )
   {
      // TODO - Create code
   }

   protected zVIEW AttachSubtaskToPane( zVIEW view, String splitName, String dialogName, String windowName, int action )
   {
      // TODO - Create code.
      // action  /* 1 - Right; 2 - Down (matching SplitFrame) */
      return view;
   }

   protected void RelinkInstanceToInstance( View tgtView, String tgtEntityName, View srcView, String srcEntityName2 )
   {
       tgtView.cursor( tgtEntityName ).linkInstances( srcView.cursor( srcEntityName2 ).getEntityInstance() );
   }

   protected int UfFormatDateTime( StringBuilder sbDayOfWeek, String szDate, String strFormat )
   {
      //TODO: This is slow.  Do we need to improve it?
      DateTime date = JoeUtils.parseStandardDateString( szDate );
      String javaFormat = JoeUtils.convertZeidonDateFormatToJavaFormat( strFormat );
      DateTimeFormatter formatter = DateTimeFormat.forPattern( javaFormat );
      sbDayOfWeek.append( formatter.print( date ) );
      return 0;
   }

   //./ ADD NAME=SetIncrementalUpdateFlags
   // Source Module=kzoeeiaa.c
   /////////////////////////////////////////////////////////////////////////////
   //
   //  ENTRY:      SetIncrementalUpdateFlags
   //
   //  PURPOSE:    To reset the record ownership and relationship ownership
   //              flags in an object instance and optionally mark the
   //              instance as either created or persistent from a
   //              database update point of view.
   //
   //  PARAMETERS: lpView        - View to instance to be reset
   //
   //              cpcEntityName - Optional Entity name, NULL to process all
   //                              Entity types
   //
   //              nOption       - marking flags
   //
   //                zSET_INCR_CREATED         0x0002
   //                     Mark all instances as created
   //
   //                zSET_INCR_PERSISTENT      0x0004
   //                     Mark all instances as existing on database
   //                     (i.e. not created)
   //
   //                zSET_INCR_UPDATED         0x0008
   //                     Mark all instances as updated
   //
   //                zSET_INCR_NOT_UPDATED     0x0010
   //                     Mark all instances as not updated
   //
   //                zSET_INCR_INCLUDED        0x0020
   //                     Mark all instances as included
   //
   //                zSET_INCR_NOT_INCLUDED    0x0040
   //                     Mark all instances as not included
   //
   //                zSET_INCR_CURSORPOS       0x0080
   //                     Do setting of entity instance at the cursor
   //                     position ONLY, requires EntityName
   //
   //                zSET_INCR_OWNERSHIP       0x0100
   //                     Set record/relationship ownership
   //
   //                NOTE: The following 4 settings SHOULD NOT be used in
   //                      Conjunction withe zSET_INCR_OWNERSHIP! If
   //                      specified, they will be IGNORED!
   //
   //                zSET_INCR_RECORDOWNER     0x0200
   //                     Force record ownership ON
   //
   //                zSET_INCR_NOT_RECORDOWNER 0x0400
   //                     Force record ownership OFF
   //
   //                zSET_INCR_RELOWNER     0x1000
   //                     Force relationship ownership ON
   //
   //                zSET_INCR_NOT_RELOWNER    0x2000
   //                     Force relationship ownership OFF
   //
   //  RETURNS:    0           - Successful
   //              zCALL_ERROR - Invalid view passed
   //
   /////////////////////////////////////////////////////////////////////////////
   public int
   SetIncrementalUpdateFlags( View   lpView,
                              String cpcEntityName,
                              int    nOption )
   {
      boolean          bCreated;
      boolean          bPersist;
      boolean          bUpdated;
      boolean          bNotUpdated;
      boolean          bIncluded;
      boolean          bNotIncluded;
      boolean          bSingleEntity;
      boolean          bAttrUpdated;
      boolean          bAttrNotUpdated;
      EntityInstance   lpRootEntityInstance;
      EntityInstance   lpEntityInstance = null;
      boolean          bMustCheckOIUpdated = false;

      if ( lpView.cursor( cpcEntityName ).isNull() )
      {
         return( zCALL_ERROR );
      }

      bSingleEntity = ((nOption & zSET_INCR_CURSORPOS) != 0);
      if ( bSingleEntity )
      {
         lpEntityInstance = lpView.cursor( cpcEntityName ).getEntityInstance();
         lpView.cursor( cpcEntityName ).setCursor( lpEntityInstance );
      }
      else
      {
         bSingleEntity = false;
      // lpEntityDef = null;
      }

      // Get the root of the object instance
      lpRootEntityInstance = lpEntityInstance;
      if ( bSingleEntity == false )
      {
         lpRootEntityInstance = lpEntityInstance;
         while ( lpRootEntityInstance.getParent() != null )
         {
            lpRootEntityInstance = lpRootEntityInstance.getParent();
         }
      }

      if ( lpRootEntityInstance == null )
      {
         return( 0 );
      }

      bCreated  = ((nOption & zSET_INCR_CREATED ) != 0);
      if ( bCreated == false )
      {
         bPersist = ((nOption & zSET_INCR_PERSISTENT) != 0);
         bUpdated = ((nOption & zSET_INCR_UPDATED) != 0);
         if ( bUpdated )
         {
         // lpEntityInstance.setUpdated();
         // lpViewOI.setUpdatedFile();
            bNotUpdated = false;
         }
         else
         {
            bNotUpdated = ((nOption & zSET_INCR_NOT_UPDATED) != 0);
         }
      }

      bIncluded = ((nOption & zSET_INCR_INCLUDED) != 0);
      if ( bIncluded == false )
      {
         bNotIncluded = ((nOption & zSET_INCR_NOT_INCLUDED) != 0);
      }
      else
      {
         bNotIncluded = false;
      }

      bAttrUpdated = ((nOption & zSET_INCR_ATTR_UPDATED) != 0);
      if ( bAttrUpdated == false )
      {
         bAttrNotUpdated = ((nOption & zSET_INCR_ATTR_NOT_UPDATED) != 0);
      }
/******
      // Loop through the entity instances.
      for ( lpEntityInstance = lpRootEntityInstance;
            lpEntityInstance != null;
            lpEntityInstance = bSingleEntity ? null : lpEntityInstance.getNextHier() ) )
      {
         LPVIEWENTITY lpTempEntityDef;
         LPVIEWATTRIB lpAttributeDef;
         boolean      bWorkEntity; // indicate entity is work or derived

         lpTempEntityDef = zGETPTR( lpEntityInstance->hEntityDef );

         // If lpEntityDef is not null, then we only want to change the flags
         // for EI's that match that LodDef.
         if ( lpEntityDef && lpTempEntityDef != lpEntityDef )
            continue;  // They don't match so continue with next EI.

         bWorkEntity = false;
         if ( lpTempEntityDef->bDerived || lpTempEntityDef->bDerivedPath ||
              lpTempEntityDef->hFirstDataRecord == 0 )
         {
            bWorkEntity = true;
         }

         if ( bCreated )
         {
            cursor.bCreated = true;
            cursor.bUpdated = false;
            lpViewOI->bUpdatedFile = true;
            if ( bWorkEntity == false )
               lpViewOI->bUpdated = true;
         }
         else
         {
            if ( bPersist )
            {
               cursor.bCreated = false;
               bMustCheckOIUpdated = true;
            }

            if ( bUpdated )
            {
               cursor.bUpdated = true;
            }
            else
            if ( bNotUpdated )
            {
               cursor.bUpdated = false;
               bMustCheckOIUpdated = true;

               /*
               HH, 2002.05.02
               This code was commented out for following reasons:
               - it is obviously wrong, the "created" flag is not turned on,
                 but it is turned off.
               - to "correct" it would mean, that turn "updated" off for a
                 deleted entity means to "undelete" it.

               If we would want that behavior, then we should correct and
               re-activate the code. However, this is a runtime change which
               can influence existing applications.

               Removing the code is not a runtime change, because of the bug it
               did not have any significant effect.

               // We don't want the entities to be flagged as updated.  If
               // the current entity is flagged as deleted then we will turn
               // on the "created" flag so the EI is considered "dead".
               if ( cursor.bDeleted )
               {
                  cursor.bCreated = false; // wrong, = true is correct
               }
               */ /****
            }
         }

         if ( bIncluded && lpEntityInstance->hParent )
            cursor.bIncluded = true;
         else
         if ( bNotIncluded )
            cursor.bIncluded = false;

         // Now check to see if we need to update the attributes.
         if ( bAttrUpdated == false && bAttrNotUpdated == false )
            continue; // Nope--continue with the next EI.

         // Set attribute flags.
         for ( lpAttributeDef = zGETPTR( lpTempEntityDef->hFirstOD_Attrib );
               lpAttributeDef;
               lpAttributeDef = zGETPTR( lpAttributeDef->hNextOD_Attrib ) )
         {
            LPATTRIBFLAGS lpAttribFlags = fnGetAttribFlagsPtr( lpEntityInstance,
                                                               lpAttributeDef );

            // Set the update flag for the entity.  Since we KNOW that either
            // bAttrUpdated flag or bAttrNotUpdated flag is true, and since they
            // can't both be true, we can just set the update flag for the
            // attribute to bAttrUpdated.
            if ( lpAttribFlags )
               lpAttribFlags->u.bFlags.bUpdated = bAttrUpdated;
         }

         if ( bAttrUpdated && cursor.bUpdated == false )
         {
            cursor.bUpdated = true;
            lpViewOI->bUpdatedFile = true;
            if ( bWorkEntity == false )
               lpViewOI->bUpdated = true;
         }
         else
         if ( bAttrNotUpdated && cursor.bUpdated )
         {
            cursor.bUpdated = false;
            bMustCheckOIUpdated = true;
         }
      }

      // if an update flag was removed, we have to re-check the
      //  OI update flags from scratch
      if ( bMustCheckOIUpdated )
         fnCheckOIUpdated( lpViewOI );
*/
      // Everything has been set, return
      return 0;
   }

   protected int FormatSubobjectOnDoc( View sourceOIView, String entityName, View viewToWindow,
                                       String reportDefName, int printFlag )
   {
      // printFlag: 0-Print;2-PrintDlg +4-force Prt/PV/PD +8-Multi Entity
      int nRC = 0;

      // TODO - Create Code. Or is this only something for windows side?

      return nRC;
   }

   protected int FormatSubobjectOnDocWithXRP( View sourceOIView, String entityName, View viewToWindow,
                                       String reportDefName, View reportDefView, int printFlag )
   {
      // printFlag: 0-Print;2-PrintDlg +4-force Prt/PV/PD +8-Multi Entity
      int nRC = 0;

      // TODO - Create Code. Or is this only something for windows side?

      return nRC;
   }


   //./ ADD NAME=GetIncrementalUpdateFlags
   // Source Module=kzoeeiaa.c
   /////////////////////////////////////////////////////////////////////////////
   //
   //  ENTRY:      GetIncrementalUpdateFlags
   //
   //  PURPOSE:    To get the value of incremental flags for an entity.
   //
   //  PARAMETERS: lpView        - View to instance to be reset
   //              cpcEntityName - Required Entity name.
   //              nOption       - marking flags
   //
   //                zSET_INCR_CREATED         0x0002
   //                     Check if entity instance is created
   //
   //                zSET_INCR_UPDATED         0x0008
   //                     Check if entity instance is updated
   //
   //                zSET_INCR_INCLUDED        0x0020
   //                     Check if entity instance is included
   //
   //                zSET_INCR_HANGING_ENTITY  0x0800
   //                     Check if entity is a hanging entity.
   //
   //                zSET_INCR_TEMPORAL_ENTITY 0x4000
   //                     Check if entity is a temporal entity.
   //
   //                zSET_INCR_DELETED         0x8000
   //                     Check if entity is deleted.  Can only be used from
   //                     a dbhandler.
   //
   //  RETURNS:    0           - Flag for entity not set.
   //              1           - Flag is set.
   //              zCALL_ERROR - Invalid view passed
   //
   /////////////////////////////////////////////////////////////////////////////
   public int
   GetIncrementalUpdateFlags( View   lpView,
                              String cpcEntityName,
                              int    nOption )
   {
      int  nRC = 0;
      if ( isValid( lpView ) && lpView.cursor( cpcEntityName ).isNull() == false )
      {
         EntityCursor cursor = lpView.cursor( cpcEntityName );
         switch ( nOption )
         {
            case zSET_INCR_CREATED:
               nRC = cursor.isCreated() ? 1 : 0;
               break;

            case zSET_INCR_UPDATED:
               nRC = cursor.isUpdated() ? 1 : 0;
               break;

            case zSET_INCR_INCLUDED:
               nRC = cursor.isIncluded() ? 1 : 0;
               break;

            case zSET_INCR_HANGING_ENTITY:
            // nRC = cursor.isHangingEntity() ? 1 : 0; // TODO: DKS???
               break;

            case zSET_INCR_TEMPORAL_ENTITY:
            // nRC = cursor.isTemporal() ? 1 : 0;  // TODO: DKS???
               break;

            case zSET_INCR_DELETED:
               nRC = cursor.isDeleted() ? 1 : 0;
               break;

            default:
               //  "KZOEE120 - Invalid position parameter"
               fnIssueCoreError( lpView.getTask(), lpView, 16, 302, nOption, "", "" );
               nRC = zCALL_ERROR;
               break;
         }
      }

      return nRC;
   }

   protected int AttributeUpdated( View view, String entityName, String attributeName )
   {
	  boolean bRC = false;

	  EntityInstance entityInstance = view.cursor(entityName).getEntityInstance();

	  AttributeDef attributeDef = view.getLodDef().getEntityDef( entityName ).getAttribute( attributeName );

	  if ( entityInstance.getAttribute(attributeDef).isUpdated() )
	     return 1;
	  else
		 return 0;
   }

   protected int zLodContainsEntity( View view, String entityName )
   {
      EntityDef ve = view.getLodDef( ).getEntityDef( entityName );
      if ( ve != null )
      {
         return 1;
      }
      else
      {
         return -1;
      }
   }

   protected int zLodContainsAttribute( View view, String entityName, String attribName )
   {
      EntityDef ve = view.getLodDef( ).getEntityDef( entityName );
      if ( ve.getAttribute( attribName ) != null )
      {
         return 1;
      }
      else
      {
         return -1;
      }
   }

   //./ ADD NAME=GetWebRedirection
   // Source Module=VmlOperation.java
   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   //
   //  DIALOG OPERATION: GetWebRedirection
   //
   //  PURPOSE:   To get the current Web KZXMLPGO "next window".
   //
   //  PARAMETERS: vSubtask    - The subtask view for the current window
   //              nWindowActionBehavior - set the action behavior
   //              stringDlgTag - Dialog name containing new window
   //              stringWndTag - Window name to which to transfer
   //
   //  RETURNS:      0  - Action performed
   //               -1  - Error locating window
   //               -2  - Action not located
   //
   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   public String
   GetWebRedirection( View  vKZXMLPGO )
   {
      StringBuilder sbFunctionCall = new StringBuilder( "" );
      StringBuilder sbDlgWnd = new StringBuilder( "" );
      StringBuilder sbDlgTag = new StringBuilder( "" );
      StringBuilder sbWndTag = new StringBuilder( "" );
      int    nRC = 0;

      if ( isValid( vKZXMLPGO ) )
      {
         GetStringFromAttribute( sbDlgTag, vKZXMLPGO, "NextDialogWindow", "DialogName" );
         GetStringFromAttribute( sbWndTag, vKZXMLPGO, "NextDialogWindow", "WindowName" );
         GetStringFromAttribute( sbFunctionCall, vKZXMLPGO, "NextDialogWindow", "FunctionCall" );
         if ( sbDlgTag.length() > 0 && sbWndTag.length() > 0 )
         {
            zstrcpy( sbDlgWnd, sbDlgTag );
            zstrcat( sbDlgWnd, sbWndTag );
         }

         DeleteEntity( vKZXMLPGO, "NextDialogWindow", zREPOS_LAST );

         if ( sbFunctionCall.toString().equals( "StartSubwindow" ) )
         {
            CreateEntity( vKZXMLPGO, "PagePath", zPOS_AFTER );
            SetAttributeFromString( vKZXMLPGO, "PagePath", "LastPageName", sbDlgWnd.toString( ) );
            nRC = 1;
         }
      }

   // TraceLineS( "", "" );
   // TraceLineS( "GetWebRedirection KZXMLPGO (post)", "" );
      TraceLine( "GetWebRedirection KZXMLPGO (post) Dlg: %s   Wnd: %s", sbDlgTag.toString( ), sbWndTag.toString( ) );
   // DisplayObjectInstance( vKZXMLPGO, "", "" );

      if ( sbDlgWnd.length() > 0 )
      {
         return sbDlgWnd.toString( ) + ".jsp";
      }
      else
      {
         return "";
      }
   }

   //./ ADD NAME=SetWebRedirection
   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   //
   //  DIALOG OPERATION: SetWebRedirection
   //
   //  PURPOSE:   To set up the Web KZXMLPGO entities.
   //
   //  PARAMETERS:  vKZXMLPGO    - The subtask view for the current window
   //               lWindowActionBehavior - set the action behavior
   //               stringDlgTag - Dialog name containing new window
   //               stringWndTag - Window name to which to transfer
   //
   //  RETURNS:      0  - Action performed
   //               -1  - Error locating window
   //               -2  - Action not located
   //
   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   public String
   SetWebRedirection( View   vKZXMLPGO,
                      int    lWindowBehavior,
                      String stringDlgTag,
                      String stringWndTag )
   {
      StringBuilder sbNextJSP = new StringBuilder( "" );
   // StringBuilder sbDlgWnd = new StringBuilder( "" );
      StringBuilder sbDlgTag = new StringBuilder( "" );
      StringBuilder sbWndTag = new StringBuilder( "" );

      TraceLine( "SetWebRedirection KZXMLPGO %s   Dlg: %s   Wnd: %s", g_Actions[ lWindowBehavior ], stringDlgTag == null ? "" : stringDlgTag, stringWndTag == null ? "" : stringWndTag );
   // DisplayObjectInstance( vKZXMLPGO, "", "" );

      if ( lWindowBehavior == zWAB_StayOnWindow )
      {
         // nothing to do
      }
      else
      {
         if ( isValid( vKZXMLPGO ) )
         {
            while ( SetCursorFirstEntity( vKZXMLPGO, "NextDialogWindow", "" ) == zCURSOR_SET )
            {
               DeleteEntity( vKZXMLPGO, "NextDialogWindow", zREPOS_NONE );
            }

         // TraceLine( "SetWebRedirection KZXMLPGO Display 1" );
         // DisplayObjectInstance( vKZXMLPGO, "", "" );
            CreateEntity( vKZXMLPGO, "NextDialogWindow", zPOS_FIRST );
         // TraceLine( "SetWebRedirection KZXMLPGO Display 2" );
         // DisplayObjectInstance( vKZXMLPGO, "", "" );
            if ( StringUtils.isBlank( stringDlgTag ) == false && StringUtils.isBlank( stringWndTag ) == false )
            {
               SetAttributeFromString( vKZXMLPGO, "NextDialogWindow", "DialogName", stringDlgTag );
               SetAttributeFromString( vKZXMLPGO, "NextDialogWindow", "WindowName", stringWndTag );
            }

         // TraceLine( "SetWebRedirection KZXMLPGO Display 3" );
         // DisplayObjectInstance( vKZXMLPGO, "", "" );
            if ( lWindowBehavior == zWAB_StayOnWindowWithRefresh )
            {
               SetAttributeFromAttribute( vKZXMLPGO, "NextDialogWindow", "DialogName", vKZXMLPGO, "DialogWindowList", "DialogName" );
               SetAttributeFromAttribute( vKZXMLPGO, "NextDialogWindow", "WindowName", vKZXMLPGO, "DialogWindowList", "WindowName" );
               SetAttributeFromAttribute( vKZXMLPGO, "NextDialogWindow", "FunctionCall", vKZXMLPGO, "DialogWindowList", "FunctionCall" );
            }
            else
            if ( lWindowBehavior == zWAB_StartTopWindow || lWindowBehavior == zWAB_ResetTopWindow )
            {
               boolean bCreated = false;

               while ( SetCursorFirstEntity( vKZXMLPGO, "DialogWindowList", "" ) == zCURSOR_SET )
               {
                  DeleteEntity( vKZXMLPGO, "DialogWindowList", zREPOS_NONE );
               }

               CreateEntity( vKZXMLPGO, "DialogWindowList", zPOS_FIRST );
               SetAttributeFromString( vKZXMLPGO, "DialogWindowList", "DialogName", stringDlgTag );
               SetAttributeFromString( vKZXMLPGO, "DialogWindowList", "WindowName", stringWndTag );

               SetAttributeFromString( vKZXMLPGO, "DialogWindowList", "FunctionCall", "StartTopSubwindow" );
               SetAttributeFromString( vKZXMLPGO, "NextDialogWindow", "FunctionCall", "StartTopSubwindow" );

               if ( CheckExistenceOfEntity( vKZXMLPGO, "TopDialogWindow" ) != zCURSOR_SET )
               {
                  bCreated = true;
                  CreateEntity( vKZXMLPGO, "TopDialogWindow", zPOS_FIRST );
               }

               if ( bCreated || lWindowBehavior == zWAB_ResetTopWindow )
               {
                  SetAttributeFromString( vKZXMLPGO, "TopDialogWindow", "DialogName", stringDlgTag );
                  SetAttributeFromString( vKZXMLPGO, "TopDialogWindow", "WindowName", stringWndTag );
                  SetAttributeFromString( vKZXMLPGO, "TopDialogWindow", "FunctionCall", "StartTopSubwindow" );
               }
            }
            else
            if ( lWindowBehavior == zWAB_StartModalSubwindow || lWindowBehavior == zWAB_StartModelessSubwindow )
            {
               CreateEntity( vKZXMLPGO, "DialogWindowList", zPOS_LAST );
               SetAttributeFromString( vKZXMLPGO, "DialogWindowList", "DialogName", stringDlgTag );
               SetAttributeFromString( vKZXMLPGO, "DialogWindowList", "WindowName", stringWndTag );

               SetAttributeFromString( vKZXMLPGO, "DialogWindowList", "FunctionCall", "StartSubwindow" );
               SetAttributeFromString( vKZXMLPGO, "NextDialogWindow", "FunctionCall", "StartSubwindow" );
            }
            else
            if ( lWindowBehavior == zWAB_ReplaceWindowWithModalWindow || lWindowBehavior == zWAB_ReplaceWindowWithModelessWindow )
            {
               if ( SetCursorLastEntity( vKZXMLPGO, "DialogWindowList", "" ) == zCURSOR_SET )
               {
                  DeleteEntity( vKZXMLPGO, "DialogWindowList", zREPOS_LAST );
               }

               CreateEntity( vKZXMLPGO, "DialogWindowList", zPOS_LAST );
               SetAttributeFromString( vKZXMLPGO, "DialogWindowList", "DialogName", stringDlgTag );
               SetAttributeFromString( vKZXMLPGO, "DialogWindowList", "WindowName", stringWndTag );

               SetAttributeFromString( vKZXMLPGO, "DialogWindowList", "FunctionCall", "ReplaceWindow" );
               SetAttributeFromString( vKZXMLPGO, "NextDialogWindow", "FunctionCall", "ReplaceWindow" );
            }
            else
            if ( lWindowBehavior == zWAB_ReturnToParentWithRefresh || lWindowBehavior == zWAB_ReturnToParent )
            {
               int nRC = zCURSOR_UNDEFINED;

               // If a "return to" window is specified, look for it in the list.  If it is found,
               // delete all following entities.  If the "return to" window is not located, just
               // do a normal return to the previous window.
               if ( StringUtils.isBlank( stringDlgTag ) == false && StringUtils.isBlank( stringWndTag ) == false )
               {
                  nRC = SetCursorFirstEntityByString( vKZXMLPGO, "DialogWindowList", "DialogName", stringDlgTag, "" );
                  while ( nRC == zCURSOR_SET )
                  {
                     if ( CompareAttributeToString( vKZXMLPGO, "DialogWindowList", "WindowName", stringWndTag ) == 0 )
                     {
                        while ( SetCursorNextEntity( vKZXMLPGO, "DialogWindowList", "" ) == zCURSOR_SET )
                        {
                           DeleteEntity( vKZXMLPGO, "DialogWindowList", zREPOS_NONE );
                        }

                        break;  // we found the right one
                     }

                     nRC = SetCursorNextEntityByString( vKZXMLPGO, "DialogWindowList", "DialogName", stringDlgTag, "" );
                  }

                  // We won't delete all remaining entities ... just do a normal return.
               // nRC = SetCursorFirstEntity( vKZXMLPGO, "DialogWindowList", "" );
               // while ( nRC == zCURSOR_SET )
               // {
               //    DeleteEntity( vKZXMLPGO, "DialogWindowList", zREPOS_NONE );
               //    nRC = SetCursorNextEntity( vKZXMLPGO, "DialogWindowList", "" );
               // }
               }

               if ( nRC != zCURSOR_SET && SetCursorLastEntity( vKZXMLPGO, "DialogWindowList", "" ) == zCURSOR_SET )
               {
               // TraceLineS( "Before DeleteEntity DialogWindowList", "" );
               // DisplayObjectInstance( vKZXMLPGO, "", "" );
               // DisplayEntityInstance( vKZXMLPGO, "DialogWindowList" );
                  DeleteEntity( vKZXMLPGO, "DialogWindowList", zREPOS_LAST );
               // SetCursorLastEntity( vKZXMLPGO, "DialogWindowList", "" );
               // DisplayEntityInstance( vKZXMLPGO, "DialogWindowList" );
               // TraceLineS( "After DeleteEntity DialogWindowList", "" );
               // DisplayObjectInstance( vKZXMLPGO, "", "" );
               }

               if ( CheckExistenceOfEntity( vKZXMLPGO, "DialogWindowList" ) != zCURSOR_SET )
               {
                  CreateEntity( vKZXMLPGO, "DialogWindowList", zPOS_LAST );
                  SetAttributeFromAttribute( vKZXMLPGO, "DialogWindowList", "DialogName", vKZXMLPGO, "TopDialogWindow", "DialogName" );
                  SetAttributeFromAttribute( vKZXMLPGO, "DialogWindowList", "WindowName", vKZXMLPGO, "TopDialogWindow", "WindowName" );
                  SetAttributeFromString( vKZXMLPGO, "DialogWindowList", "FunctionCall", "ReturnToParent" );
               }

               SetAttributeFromAttribute( vKZXMLPGO, "NextDialogWindow", "DialogName", vKZXMLPGO, "DialogWindowList", "DialogName" );
               SetAttributeFromAttribute( vKZXMLPGO, "NextDialogWindow", "WindowName", vKZXMLPGO, "DialogWindowList", "WindowName" );
               SetAttributeFromAttribute( vKZXMLPGO, "NextDialogWindow", "FunctionCall", vKZXMLPGO, "DialogWindowList", "FunctionCall" );
            }
            else
            if ( lWindowBehavior == zWAB_ReturnToTopWindow )
            {
               if ( SetCursorFirstEntity( vKZXMLPGO, "DialogWindowList", "" ) == 0 )
               {
                  while ( SetCursorNextEntity( vKZXMLPGO, "DialogWindowList", "" ) == zCURSOR_SET )
                  {
                     DeleteEntity( vKZXMLPGO, "DialogWindowList", zREPOS_NONE );
                  }

                  SetCursorFirstEntity( vKZXMLPGO, "DialogWindowList", "" );
               }

               if ( CheckExistenceOfEntity( vKZXMLPGO, "DialogWindowList" ) != zCURSOR_SET )
               {
                  CreateEntity( vKZXMLPGO, "DialogWindowList", zPOS_LAST );
                  SetAttributeFromString( vKZXMLPGO, "DialogWindowList", "DialogName", stringDlgTag );
                  SetAttributeFromString( vKZXMLPGO, "DialogWindowList", "WindowName", stringWndTag );
                  SetAttributeFromString( vKZXMLPGO, "DialogWindowList", "FunctionCall", "ReturnToTopWindow" );
               }

               SetAttributeFromAttribute( vKZXMLPGO, "NextDialogWindow", "DialogName", vKZXMLPGO, "DialogWindowList", "DialogName" );
               SetAttributeFromAttribute( vKZXMLPGO, "NextDialogWindow", "WindowName", vKZXMLPGO, "DialogWindowList", "WindowName" );
               SetAttributeFromAttribute( vKZXMLPGO, "NextDialogWindow", "FunctionCall", vKZXMLPGO, "DialogWindowList", "FunctionCall" );
            }
            else
            {
               SetAttributeFromString( vKZXMLPGO, "NextDialogWindow", "FunctionCall", "???????" );
            }
         }
      }

      if ( isValid( vKZXMLPGO ) && CheckExistenceOfEntity( vKZXMLPGO, "NextDialogWindow" ) == zCURSOR_SET )
      {
         GetStringFromAttribute( sbDlgTag, vKZXMLPGO, "NextDialogWindow", "DialogName" );
         GetStringFromAttribute( sbWndTag, vKZXMLPGO, "NextDialogWindow", "WindowName" );
      }

      if ( sbDlgTag.length() == 0 || sbWndTag.length() == 0 )
      {
         zstrcpy( sbDlgTag, stringDlgTag );
         zstrcpy( sbWndTag, stringWndTag );
      }

      if ( sbDlgTag.length() > 0 && sbWndTag.length() > 0 )
      {
         zstrcpy( sbNextJSP, sbDlgTag );
         zstrcat( sbNextJSP, sbWndTag );
         zstrcat( sbNextJSP, ".jsp" );
      }

   // DisplayObjectInstance( vKZXMLPGO, "", "" );
      return sbNextJSP.toString();
   }

   public int
   CallDialogOperation( View vSubtask, String szFormValidationDLL, String szFormValidationOperation )
   {
      // TODO Auto-generated method stub
      return 0;
   }

   public int SaveFeedback( String viewName, String dialogTag, String windowTag, String feedback )
   {
      String szUserId = SfGetUserIdForTask( task );
      View v = task.getViewByName( viewName );

      if ( v == null )
      {
         // Assume LOD name matches view name since this is not a delivered operation.
         v = task.activateEmptyObjectInstance( viewName );
         v.setName( viewName );
      }

      // if ( v.cursor( "Feedback" ).checkExistenceOfEntity() != zCURSOR_SET )
      if ( StringUtils.isBlank( feedback ) == false )
      {
         v.cursor( "Feedback" ).createEntity( CursorPosition.LAST );
         v.cursor( "Feedback" ).getAttribute( "UserId" ).setValue( szUserId );
         v.cursor( "Feedback" ).getAttribute( "Dialog").setValue( dialogTag );
         v.cursor( "Feedback" ).getAttribute( "Window" ).setValue( windowTag );
         v.cursor( "Feedback" ).getAttribute( "Comment" ).setValue( feedback );
         CommitObjectInstance( v );
         return 0;
      }

      return -1;
   }

   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////////////////////////////////

   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   //
   // OPERATION: CreateMemoryHandle
   //
   // N.B.  The user is responsible for calling DeleteMemoryHandle with the
   // handle returned from this call.  If not, a memory leak will occur!!!
   //
   ///////////////////////////////////////////////////////////////////////////////////////////////////////

   private MemoryList memoryList = null;

   public int
   CreateMemoryHandle( int lInitialSize )
   {
      if ( memoryList == null )
      {
          memoryList = new MemoryList( );
      }

      if ( lInitialSize < 8192 )
      {
          lInitialSize = 8192;
      }

      int memoryHandle = memoryList.memoryCount.incrementAndGet( );
      memoryList.memoryMap.putIfAbsent( memoryHandle, new MemoryItem( lInitialSize ) );

      return memoryHandle;
   }

   public void
   DeleteMemoryHandle( int hMemory )
   {
      MemoryItem item = memoryList.memoryMap.get( hMemory );
      memoryList.memoryMap.remove( item );
   }

   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   //
   // OPERATION: AddAttributeToMemory
   //
   // Returns: >= 0 - Resultant length of string in memory
   //                 Attribute successfully retrieved
   //           < 0 - Error retrieving attribute
   //
   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   public int
   AddAttributeToMemory( int    hMemory,
                         View   vApp,
                         String cpcEntityName,
                         String cpcAttributeName,
                         int    lFlag )
   {
      String pch = null;

      pch = GetStringFromAttribute( pch, vApp, cpcEntityName, cpcAttributeName );
      if ( pch != null )
      {
         return( AddStringToMemory( hMemory, pch, lFlag ) );
      }
      else
      {
         return( zCALL_ERROR );
      }
   }

   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   //
   // OPERATION: AddStringToMemory
   //
   // Parameters:  cpcString - address of string to add
   //                  lFlag - 0 ==> just add string as is
   //                          1 ==> add string surrounded by single quotes
   //                          2 ==> add string surrounded by double quotes
   //                          4 ==> add string and terminate with CRLF
   //
   // Returns: Resultant length of string in memory
   //
   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   public int
   AddStringToMemory( int    hMemory,
                      String cpcString,
                      int    lFlag )
   {
      MemoryItem item = memoryList.memoryMap.get( hMemory );
      return( item.AddStringToMemory( cpcString, lFlag ) );
   }

   public void
   ClearMemory( int    hMemory )
   {
      MemoryItem item = memoryList.memoryMap.get( hMemory );
      item.ClearMemory( );
   }

   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   //
   // OPERATION: SetMemoryToAttribute
   //
   // Returns: 0  - Attribute successfully set
   //         otw - Error setting attribute
   //
   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   public int
   SetMemoryToAttribute( int    hMemory,
                         View   vApp,
                         String cpcEntityName,
                         String cpcAttributeName )
   {
      MemoryItem item = memoryList.memoryMap.get( hMemory );
      return( SetAttributeFromString( vApp, cpcEntityName, cpcAttributeName, item.toString( ) ) );
   }

   private ClusterInfo getClusterInfo()
   {
       ClusterInfo info = task.getTask().getCacheMap().get( ClusterInfo.class );
       if ( info == null )
           info = task.getTask().getCacheMap().put( ClusterInfo.class, new ClusterInfo() );

       return info;
   }

   /**
    * Information for storing cluster information in a task.  This is used to translate between
    * VML clusters and JOE commits.
    *
    * @author dgc
    *
    */
   private static class ClusterInfo
   {
      private final AtomicInteger clusterCount = new AtomicInteger( 0 );
      private final ConcurrentHashMap> clusterMap = new ConcurrentHashMap>();

      private int createCluster()
      {
          int num = clusterCount.incrementAndGet();
          clusterMap.put( num, new ArrayList() );
          return num;
      }

      private void deleteCluster( int clusterNum )
      {
          clusterMap.remove( clusterNum );
      }

      private List getViewList( int clusterNum )
      {
          return clusterMap.get( clusterNum );
      }
   }


   /***
    * Contains information regarding memory handles for a task.
    ***/

   private static class MemoryList
   {
      private final AtomicInteger memoryCount = new AtomicInteger( 0 );
      private final ConcurrentHashMap memoryMap = new ConcurrentHashMap();
   }

   private static class MemoryItem
   {
      private CharBuffer cb = null;
      private int nLth;

      private MemoryItem( int lInitialSize )
      {
         cb = CharBuffer.allocate( lInitialSize );
         ClearMemory( );
      }

      private void ClearMemory( )
      {
         nLth = 0;
         cb.clear( );        // one of these two lines should be
         cb.put( 0, '\0' );  // enough in and of itself!!!
      }

      private int AddStringToMemory( String s, int lFlag )
      {
         int k;

         if ( (lFlag & 1) != 0 )
         {
            cb.put( nLth++, '\'' );
         }

         if ( (lFlag & 2) != 0 )
         {
            cb.put( nLth++, '"' );
         }

         for ( k = 0; k < s.length( ); k++ )
         {
            cb.put( nLth++, s.charAt( k ) );
         }

         if ( (lFlag & 1) != 0 )
         {
            cb.put( nLth++, '\'' );
         }

         if ( (lFlag & 2) != 0 )
         {
            cb.put( nLth++, '"' );
         }

         if ( (lFlag & 4) != 0 )
         {
            cb.put( nLth++, '\n' );
         }

         return nLth;  // current used length of charBuffer
      }
   }

   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////////////////////////////////

   public static class ZNameItem
   {
      private String m_csName;
      private int    m_lFlag;

      public ZNameItem( String cpcName, int lFlag )
      {
         m_csName = cpcName;
         m_lFlag = lFlag;
      }

      public String getName( ) { return m_csName; }
      public void setName( String csName ) { m_csName = csName; }
      public int getFlag( ) { return m_lFlag; }
      public void setFlag( int lFlag ) { m_lFlag = lFlag; }
   }

   // Determine if the error list (tab-separated strings) contain the widget Tag.  If so,
   // return the message associated with that Tag, otherwise return empty string.
   public static final String CheckError( String widgetTag, String errorList )
   {
      // Parse a tab/newline-separated string (e.g. "Y\tChemicalName\tMax length exceeded\t\nMapping value in error\t\nY\tPercent\tInvalid numeric\t\n6.84%\t\n ...")
      String[] fields = errorList.split( "\t\n" );

      int arraySize = fields.length - 1; // get the size of the array
      for ( int k = 0; k < arraySize; k += 2 )  // skip every other one
      {
         String[] tagError = fields[ k ].split( "\t" );
         if ( widgetTag.compareTo( tagError[ 1 ] ) == 0 )
         {
            return( fields[ k + 1 ] );
         }
      }

      return "";
   }

/**
 * Provides facilities to sanitize HTML containing unwanted or invalid tags into clean HTML.
 * 

* The sanitation process consists of the following steps: *

    *
  • * Find all potential HTML tags in the input text. For each tag: *
      *
    • If it is one of the allowed tags * (<br>, <p>, <b>, <i>, * <ol>, <ul>, <li>, <a>) then: *
        *
      • If a matching end tag is required, check that the end tag exists and is correctly nested. If not, reject the tag. *
      • Check that the element is in a valid position (e.g. <li> elements must be inside <ul> or <ol> elements). If not, reject the element. *
      • Keep only the allowed attributes (id, class, href, target, title) and strip any others. *
      • Ensure all attributes are XHTML compliant (all values enclosed in double quotes and fully encoded) *
      • Ensure tags are XHTML compliant (convert to lower case and add closing slash to empty element tag, e.g. <br />) *
      *
    • *
    • If it is not one of the allowed tags or was rejected for any reason: *
        *
      • If the method strips invalid markup, completely remove the tag or element from the output, * otherwise encode it so that it renders verbatim. *
      *
    • *
    *
  • *
  • * If the formatWhiteSpace option is enabled: *
      *
    • Line breaks, being Carriage Return (U+000D) or Line Feed (U+000A) characters, and Form Feed characters (U+000C) * are converted to "<br />". CR/LF pairs are treated as a single line break. *
    • Multiple consecutive spaces are converted so that every second space is converted to "&nbsp;" * while ensuring the last is always a normal space. *
    • Tab characters (U+0009) are converted as if they were four consecutive spaces. *
    *
  • *
  • Ensure all remaining text is fully encoded. *
*/ public class HTMLSanitizer { public HTMLSanitizer( String validHTML_TagList, String validHTML_AttributeList ) // private ==> not instantiable { if ( StringUtils.isBlank( validHTML_TagList ) ) { VALID_ELEMENT_NAMES = ImmutableSet.of( HTMLElementName.A, HTMLElementName.B, HTMLElementName.BR, HTMLElementName.I, HTMLElementName.LI, HTMLElementName.OL, HTMLElementName.P, HTMLElementName.STRONG, HTMLElementName.SUB, HTMLElementName.U, HTMLElementName.UL ); } else { String[] strings = validHTML_TagList.split( "[, ]" ); // split() uses reg-ex VALID_ELEMENT_NAMES = ImmutableSet.copyOf( strings ); } if ( StringUtils.isBlank( validHTML_AttributeList ) ) { VALID_ATTRIBUTE_NAMES = ImmutableSet.of( "class", "href", "id", "target", "title" ); // If set is not immutable, use... // VALID_ATTRIBUTE_NAMES = Sets.newHashSet( "class", // "href", // "id", // "target", // "title" ); } else { String[] strings = validHTML_TagList.split( "[, ]" ); VALID_ATTRIBUTE_NAMES = ImmutableSet.copyOf( strings ); } } // list of HTML elements that will be retained in the final output: private final Set VALID_ELEMENT_NAMES; // list of HTML attributes that will be retained in the final output: private final Set VALID_ATTRIBUTE_NAMES; private final Object VALID_MARKER=new Object(); /** * Returns a sanitized version of the specified HTML, encoding any unwanted tags. *

* Calling this method is equivalent to {@link #encodeInvalidMarkup(String,boolean) encodeInvalidMarkup(pseudoHTML,false)}. *

*

*
Example:
*
* * * * *
Method call:
HTMLSanitizer.encodeInvalidMarkup("<P><u>Line   1</u>\n<b>Line   2</b>\n<script>doBadStuff()</script>")
Output:
<p>&lt;u&gt;Line   1&lt;/u&gt;\n<b>Line   2</b>\n&lt;script&gt;doBadStuff()&lt;/script&gt;</p>
Rendered output:

<u>Line 1</u> Line 2 <script>doBadStuff()</script>

* In this example: *
    *
  • The <P> tag is kept and converted to lower case *
  • The optional end tag </p> is added *
  • The <b> element is kept *
  • The unwanted <u> and <script> elements are encoded so that they render verbatim *
*
*
* * @param pseudoHTML The potentially invalid HTML to sanitize. * @return a sanitized version of the specified HTML, encoding any unwanted tags. */ public String encodeInvalidMarkup(String pseudoHTML) { return encodeInvalidMarkup(pseudoHTML,false); } /** * Returns a sanitized version of the specified HTML, encoding any unwanted tags. *

* Encoding unwanted and invalid tags results in them appearing verbatim in the rendered output, * helping to highlight the problem so that the source HTML can be fixed. *

* Specifying a value of true as an argument to the formatWhiteSpace parameter * results in the formatting of white space as described in the sanitisation process in the class description above. *

*

*
Example:
*
* * * * *
Method call:
HTMLSanitizer.encodeInvalidMarkup("<P><u>Line   1</u>\n<b>Line   2</b>\n<script>doBadStuff()</script>",true)
Output:
<p>&lt;u&gt;Line &nbsp; 1&lt;/u&gt;<br /><b>Line &nbsp; 2</b><br />&lt;script&gt;doBadStuff()&lt;/script&gt;</p>
Rendered output:

<u>Line   1</u>
Line   2
<script>doBadStuff()</script>

* In this example: *
    *
  • The <P> tag is kept and converted to lower case *
  • The optional end tag </p> is added *
  • The <b> element is kept *
  • The unwanted <u> and <script> elements are encoded so that they render verbatim *
  • The line feed characters are converted to <br /> elements *
  • Non-breaking spaces (&nbsp;) are added to ensure the multiple spaces are rendered as they appear in the input. *
*
*
* * @param pseudoHTML The potentially invalid HTML to sanitize. * @param formatWhiteSpace Specifies whether white space should be marked up in the output. * @return a sanitized version of the specified HTML, encoding any unwanted tags. */ public String encodeInvalidMarkup(String pseudoHTML, boolean formatWhiteSpace) { return sanitize(pseudoHTML,formatWhiteSpace,false); } /** * Returns a sanitized version of the specified HTML, stripping any unwanted tags. *

* Calling this method is equivalent to {@link #stripInvalidMarkup(String,boolean) stripInvalidMarkup(pseudoHTML,false)}. *

*

*
Example:
*
* * * * *
Method call:
HTMLSanitizer.stripInvalidMarkup("<P><u>Line   1</u>\n<b>Line   2</b>\n<script>doBadStuff()</script>")
Output:
<p>Line   1\n<b>Line   2</b>\n</p>
Rendered output:

Line 1 Line 2

* In this example: *
    *
  • The <P> tag is kept and converted to lower case *
  • The optional end tag </p> is added *
  • The <b> element is kept *
  • The unwanted <u> and <script> elements are stripped from the output *
*
*
* * @param pseudoHTML The potentially invalid HTML to sanitize. * @return a sanitized version of the specified HTML, stripping any unwanted tags. */ public String stripInvalidMarkup(String pseudoHTML) { return stripInvalidMarkup(pseudoHTML,false); } /** * Returns a sanitized version of the specified HTML, stripping any unwanted tags. *

* Stripping unwanted and invalid tags is the preferred option if the output is for public consumption. *

* Specifying a value of true as an argument to the formatWhiteSpace parameter * results in the formatting of white space as described in the sanitisation process in the class description above. *

*

*
Example:
*
* * * * *
Method call:
HTMLSanitizer.stripInvalidMarkup("<P><u>Line   1</u>\n<b>Line   2</b>\n<script>doBadStuff()</script>",true)
Output:
<p>Line &nbsp; 1<br /><b>Line &nbsp; 2</b><br /></p>
Rendered output:

Line   1
Line   2

* In this example: *
    *
  • The <P> tag is kept and converted to lower case *
  • The optional end tag </p> is added *
  • The <b> element is kept *
  • The unwanted <u> and <script> elements are stripped from the output *
  • The line feed characters are converted to <br /> elements *
  • Non-breaking spaces (&nbsp;) are added to ensure the multiple spaces are rendered as they appear in the input. *
*
*
* * @param pseudoHTML The potentially invalid HTML to sanitize. * @param formatWhiteSpace Specifies whether white space should be marked up in the output. * @return a sanitized version of the specified HTML, stripping any unwanted tags. */ public String stripInvalidMarkup(String pseudoHTML, boolean formatWhiteSpace) { return sanitize(pseudoHTML,formatWhiteSpace,true); } private String sanitize(String pseudoHTML, boolean formatWhiteSpace, boolean stripInvalidElements) { Source source=new Source(pseudoHTML); source.fullSequentialParse(); OutputDocument outputDocument=new OutputDocument(source); List tags=source.getAllTags(); int pos=0; for (Tag tag : tags) { if (processTag(tag,outputDocument)) { tag.setUserData(VALID_MARKER); } else { if (!stripInvalidElements) { continue; // element will be encoded along with surrounding text } outputDocument.remove(tag); } reencodeTextSegment(source,outputDocument,pos,tag.getBegin(),formatWhiteSpace); pos=tag.getEnd(); } reencodeTextSegment(source,outputDocument,pos,source.getEnd(),formatWhiteSpace); return outputDocument.toString(); } private boolean processTag(Tag tag, OutputDocument outputDocument) { String elementName=tag.getName(); if (!VALID_ELEMENT_NAMES.contains(elementName)) { return false; } if (tag.getTagType()==StartTagType.NORMAL) { Element element=tag.getElement(); if (HTMLElements.getEndTagRequiredElementNames().contains(elementName)) { if (element.getEndTag()==null) { return false; // reject start tag if its required end tag is missing } } else if (HTMLElements.getEndTagOptionalElementNames().contains(elementName)) { if (elementName.equals( HTMLElementName.LI ) && !isValidLITag(tag)) { return false; // reject invalid LI tags } if (element.getEndTag() == null) { outputDocument.insert(element.getEnd(),getEndTagHTML(elementName)); // insert optional end tag if it is missing } } outputDocument.replace(tag,getStartTagHTML(element.getStartTag())); } else if (tag.getTagType() == EndTagType.NORMAL) { if (tag.getElement() == null) { return false; } // reject end tags that aren't associated with a start tag if (elementName.equals( HTMLElementName.LI ) && !isValidLITag(tag)) { return false; } // reject invalid LI tags outputDocument.replace(tag,getEndTagHTML(elementName)); } else { return false; // reject abnormal tags } return true; } private boolean isValidLITag(Tag tag) { Element parentElement = tag.getElement().getParentElement(); if (parentElement == null) { return false; // ignore LI elements without a parent } if (parentElement.getStartTag().getUserData() != VALID_MARKER) { return false; // ignore LI elements who's parent is not valid } return parentElement.getName().equals( HTMLElementName.UL ) || parentElement.getName().equals( HTMLElementName.OL ); // only accept LI tags who's immediate parent is UL or OL. } private void reencodeTextSegment(Source source, OutputDocument outputDocument, int begin, int end, boolean formatWhiteSpace) { if (begin>=end) { return; } Segment textSegment=new Segment(source,begin,end); String decodedText=CharacterReference.decode(textSegment); String encodedText=formatWhiteSpace ? CharacterReference.encodeWithWhiteSpaceFormatting(decodedText) : CharacterReference.encode(decodedText); outputDocument.replace(textSegment,encodedText); } private CharSequence getStartTagHTML(StartTag startTag) { // tidies and filters out non-approved attributes StringBuilder sb = new StringBuilder(); sb.append('<').append(startTag.getName()); for (Attribute attribute : startTag.getAttributes()) { if (VALID_ATTRIBUTE_NAMES.contains(attribute.getKey())) { sb.append(' ').append(attribute.getName()); if (attribute.getValue() != null) { sb.append("=\""); sb.append(CharacterReference.encode(attribute.getValue())); sb.append('"'); } } } if (startTag.getElement().getEndTag() == null && !HTMLElements.getEndTagOptionalElementNames().contains(startTag.getName())) { sb.append(" /"); } sb.append('>'); return sb; } private String getEndTagHTML(String tagName) { return "'; } ////////////////////////////////////////////////////////////////////////////////////// // THE METHODS BELOW ARE USED ONLY FOR DEMONSTRATING THE FUNCTIONALITY OF THE CLASS // ////////////////////////////////////////////////////////////////////////////////////// // See test/src/samples/HTMLSanitizerTest.java for a comprehensive test suite. public void testHTMLSanitizer() //throws Exception { System.out.println("Examples of HTMLSanitizer.encodeInvalidMarkup:"); System.out.println("----------------------------------------------\n"); displayEncodeInvalidMarkup("ab & c","encode text"); displayEncodeInvalidMarkup("abc def geh"," element not allowed"); displayEncodeInvalidMarkup("

abc","add optional end tag"); displayEncodeInvalidMarkup("","remove potentially dangerous script"); displayEncodeInvalidMarkup("

abc

","keep approved attributes but strip non-approved attributes"); displayEncodeInvalidMarkup("

abc

","tidy up attributes to make them XHTML compliant"); displayEncodeInvalidMarkup("List:
  • A
  • B
  • C
","inserts optional end tags"); System.out.println("Examples of HTMLSanitizer.stripInvalidMarkup:"); System.out.println("---------------------------------------------\n"); displayStripInvalidMarkup("ab & c","encode text"); displayStripInvalidMarkup("abc def geh"," element not allowed"); displayStripInvalidMarkup("

abc","add optional end tag"); displayStripInvalidMarkup("","remove potentially dangerous script"); displayStripInvalidMarkup("

abc

","keep approved attributes but strip non-approved attributes"); displayStripInvalidMarkup("

abc

","tidy up attributes to make them XHTML compliant"); displayStripInvalidMarkup("List:
  • A
  • B
  • C
","inserts optional end tags"); displayStripInvalidMarkup("List:
  • A
  • B
  • C","missing required
      or
        element"); displayStripInvalidMarkup("List:
        • A
        • B
        • C
        ","
      1. is invalid as it is not directly under
          or
            "); System.out.println("Examples of HTMLSanitizer.stripInvalidMarkup with formatWhiteSpace=true:"); System.out.println("------------------------------------------------------------------------\n"); displayStripInvalidMarkup("abc\ndef",true,"convert LF to
            "); displayStripInvalidMarkup(" abc",true,"ensure consecutive spaces are rendered"); displayStripInvalidMarkup("\tabc",true,"convert TAB to equivalent of four spaces"); } private void displayEncodeInvalidMarkup(String input, String explanation) { display(input, explanation, encodeInvalidMarkup(input)); } private void displayStripInvalidMarkup(String input, String explanation) { display(input, explanation, stripInvalidMarkup(input)); } private void displayStripInvalidMarkup(String input, boolean formatWhiteSpace, String explanation) { display(input, explanation, stripInvalidMarkup(input, formatWhiteSpace)); } private void display(String input, String explanation, String output) { System.out.println(explanation+":\ninput : "+input+"\noutput: "+output+"\n"); } } /////////////////////////////////////////////////////////////////////////////////////////////////////// // // RemoveFormattingFromHTML_Attr // // vHTML HTML View // cpcHTML_Entity HTML entity // cpcHTML_Attribute HTML attribute // cpcValidHTML_TagList Valid HTML tags (comma separated list that will // not be removed) // /////////////////////////////////////////////////////////////////////////////////////////////////////// public int RemoveFormattingFromHTML_Attr( View vHTML, String cpcHTML_Entity, String cpcHTML_Attribute, String cpcValidHTML_TagList ) { String pchHTML = null; int lth; pchHTML = GetAddrForAttribute( pchHTML, vHTML, cpcHTML_Entity, cpcHTML_Attribute ); lth = zstrlen( pchHTML ); String pchUnformattedHTML = pchHTML; pchHTML = RemoveFormattingFromHTML_Text( vHTML, pchUnformattedHTML, lth, cpcValidHTML_TagList ); SetAttributeFromString( vHTML, cpcHTML_Entity, cpcHTML_Attribute, pchHTML ); // done with pchUnformattedHTML return 0; } /////////////////////////////////////////////////////////////////////////////////////////////////////// // // RemoveFormattingFromHTML_Text // // vTaskView Task View // pchHTML_Text Text potentially containing HTML tags // lMaxLth Maximum length of HTML text // cpcValidHTML_TagList Valid HTML tags (comma separated list of tags // that will not be removed) // /////////////////////////////////////////////////////////////////////////////////////////////////////// public String RemoveFormattingFromHTML_Text( View vTaskView, String strHTML_Text, int lMaxLth, String strValidHTML_TagList ) { if ( StringUtils.isBlank( strHTML_Text ) ) { TraceLine( "RemoveFormattingFromHTML_Text HTML is empty", "" ); return ""; } else { HTMLSanitizer xx = new HTMLSanitizer( strValidHTML_TagList, "" ); String strPage = xx.sanitize( strHTML_Text, true, true ); // done with pParseHTML int lth = strPage.length( ); if ( lth > lMaxLth ) { TraceLine( "RemoveFormattingFromHTML length: %d exceeded maximum: %d", lth, lMaxLth ); TraceLineS( "RemoveFormattingFromHTML original: ", strHTML_Text ); TraceLineS( "RemoveFormattingFromHTML reformat: ", strPage ); } return strPage; } } public final String SanitizeHTML( String strHTML, String validHTML_TagList, String validHTML_AttributeList ) { if ( StringUtils.isBlank( strHTML ) ) { // TraceLine( "SanitizeHTML HTML is empty", "" ); return ""; } else { HTMLSanitizer xx = new HTMLSanitizer( validHTML_TagList, validHTML_AttributeList ); String strPage = xx.stripInvalidMarkup( strHTML, false ); // done with pParseHTML return strPage; } } // Valid characters: Letters (a-z A-Z) Digits (0-9) Underscore (_) Hyphen (-) Space Dot (.) public String RemoveInvalidCharsFromFilename( String in ) { StringBuilder sbFileName = new StringBuilder( in ); RemoveInvalidCharsFromFilename( sbFileName ); return sbFileName.toString(); } // Valid characters: Letters (a-z A-Z) Digits (0-9) Underscore (_) Hyphen (-) Space Dot (.) public int RemoveInvalidCharsFromFilename( StringBuilder sbFileName ) { String in = sbFileName.toString(); TraceLineS( "RemoveInvalidCharsFromFilename original: ", in ); char ch; int k; int pos = 0; for ( k = 0; k < in.length(); k++ ) { ch = in.charAt( k ); if ( (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '-' || ch == '.' || ch == ' ' ) { sbFileName.setCharAt( pos++, ch ); } } sbFileName.setLength( pos ); TraceLineS( "RemoveInvalidCharsFromFilename validated: ", sbFileName.toString() ); return sbFileName.length(); } public int ConvertXML_SpecialCharacters( View vReportDef, StringBuilder sb_szConvertedString, StringBuilder sb_szSourceString, int MaxLth ) { String szOutput=sb_szSourceString.toString(); szOutput = szOutput.replace("&","&"); szOutput = szOutput.replace("<","<"); szOutput = szOutput.replace(">",">"); szOutput = szOutput.replace("\"","""); szOutput = szOutput.replace("\'","'"); // KJS 12/17/13 - I am using to put in a newline character. But I don't // want the & to have been switched to &. See how this works... // szOutput = szOutput.replace("&#xA;"," "); sb_szConvertedString.append(szOutput); return( 0 ); } /*

            {{ProductName}}, EPA Reg. No. {{EPA_RegNo}}

            {{PageOf}}

            2-3-15

            (Note to Reviewer: Text in { } is optional. Brackets [ ] indicate that at least one option within the brackets must be used in the final label text. Parentheticals ( ) are meant to appear on final label. “This product” can be substituted with actual product name.)

            EPA Accepted 5-5-15

            */ private static String RemoveHtmlTag( String strHtml, String strTag, String strReplaceTag ) { String openTag = "<" + strTag; String closeTag = ""; String strTemp; int nOpenPos; int nPos; int nEndPos; while ( (nOpenPos = strHtml.indexOf( openTag )) >= 0 ) { nPos = nOpenPos + openTag.length(); nEndPos = strHtml.indexOf( '>', nPos ); if ( nEndPos >= 0 ) { nEndPos++; strTemp = strHtml.substring( 0, nOpenPos ); nOpenPos = strHtml.indexOf( closeTag, nEndPos ); if ( nOpenPos >= 0 ) { strTemp += strHtml.substring( nEndPos, nOpenPos ); if ( strReplaceTag != null ) strTemp += strReplaceTag; nOpenPos += closeTag.length(); strTemp += strHtml.substring( nOpenPos ); strHtml = strTemp; } else { break; } } else { break; } } return strHtml; } public static String TrimTinyHtml( String strHtmlEnclosedValue ) { if ( strHtmlEnclosedValue == null || strHtmlEnclosedValue.isEmpty() ) { return ""; } int nStartPos = strHtmlEnclosedValue.indexOf( "" ); if ( nStartPos < 0 ) nStartPos = 0; else nStartPos += 6; // length of "" int nEndPos = strHtmlEnclosedValue.lastIndexOf( "" ); if ( nEndPos < 0 ) strHtmlEnclosedValue = strHtmlEnclosedValue.substring( nStartPos ); else strHtmlEnclosedValue = strHtmlEnclosedValue.substring( nStartPos, nEndPos ); strHtmlEnclosedValue = RemoveHtmlTag( strHtmlEnclosedValue, "span", null ); strHtmlEnclosedValue = RemoveHtmlTag( strHtmlEnclosedValue, "p", "
            " ); // strHtmlEnclosedValue = RemoveHtmlTag( strHtmlEnclosedValue, "p", "\r\n" ); if ( (nEndPos = strHtmlEnclosedValue.indexOf( "\r\n" )) == 0 ) { strHtmlEnclosedValue = strHtmlEnclosedValue.substring( 2 ); } if ( (nEndPos = strHtmlEnclosedValue.lastIndexOf( "\r\n" )) >= 0 ) { if ( nEndPos == strHtmlEnclosedValue.length() - 2 ) strHtmlEnclosedValue = strHtmlEnclosedValue.substring( 0, nEndPos ); } if ( (nEndPos = strHtmlEnclosedValue.lastIndexOf( "
            " )) >= 0 ) { if ( nEndPos == strHtmlEnclosedValue.length() - 4 ) { strHtmlEnclosedValue = strHtmlEnclosedValue.substring( 0, nEndPos ); } } return strHtmlEnclosedValue; } // This function checks for the existence of the specified file/directory. // If it is a check for a valid file, that's all we do. For a directory, // if the directory does not exist (and bCheckCreate is TRUE) the directory is created. // // Return: // 1 - the directory exists (or was created) // 0 - the directory does not exist or was not specified or could not be created public static int SysValidDirOrFile( String directory, int bDirectory, int bCheckCreate, int nMaxPathLth ) { if ( directory == null || directory.isEmpty() ) return 0; // no directory was specified // file.exists() == false ==> file.isDirectory() == false AND file.isFile() == false // file.isDirectory() == true OR file.isFile() == true ==> file.exists() == true // file.isDirectory() == true ==> file.isFile() == false // file.isFile() == true ==> file.isDirectory() == false File file = new File( directory ); boolean exists; if ( file.exists() ) { if ( (bDirectory != 0 && file.isDirectory()) || (bDirectory == 0 && file.isFile()) ) exists = true; else exists = false; } else { if ( bDirectory != 0 ) { // mkdirs() creates the directory specified including any necessary parent directories. // It will return true if the directory is created successfully or false otherwise. exists = file.mkdirs(); if ( exists == false ) { // task.log().error( "SysValidDirOrFile unable to create directory: " + directory ); } } else { exists = false; } } return exists ? 1 : 0; } // NOT EXACTLY SURE WHAT TO DO HERE... THE FOLLOWING CODE IS TECHNICALLY CREATED FROM TZ VML CODE // AND IS IN ZeidonTools... but then we want to call that code from here... but I'm not sure that // DG wants the ZeidonTools to need to be in JOE... which perhaps vmlOperations whould be moved // out as well... So I am copying these three Operations into vmlOperations temporarily to see how // things work... //: VIEW vReportDef BASED ON LOD TZRPSRCO public static String FindOpenFile( Task task ) { String szDir; String szFileName; String szFileExt; szFileName = null; View vKZXMLPGO = task.getViewByName( WEB_SESSION_VIEW_NAME ); szFileName = vKZXMLPGO.cursor("Session").getAttribute( "PrintFileName" ).getString(); szFileExt = vKZXMLPGO.cursor("Session").getAttribute( "PrintFileType" ).getString(); if ( szFileName != null && szFileName.isEmpty() == false ) { szDir = "./pdf/"; if ( szFileName.contains(".") == false ) { szFileName = szFileName + "."; if ( szFileExt != null ) { szFileName = szFileName + szFileExt; } else { szFileName = szFileName + "html"; } } if ( szFileName.startsWith( "\\" ) == false && szFileName.startsWith( "/" ) == false && szFileName.startsWith( "./" ) == false ) { szFileName = szDir + szFileName; } } else { szFileName = ""; } //TraceLineS( "Get Open File ===========>> ", szFileName ); vKZXMLPGO.cursor("Session").getAttribute( "PrintFileName" ).setValue( "" ); vKZXMLPGO.cursor("Session").getAttribute( "PrintFileType" ).setValue( "" ); // Don't think we will need to do the following...? /* nRC = SysMakeWebFileName( szTemp, vSubtask, 0 ); strcat( szTemp, ".html" ); nRC = GetViewByName( &vTemp, szTemp, vSubtask, zLEVEL_TASK ); if ( vTemp ) nRC = DropNameForView( vTemp, szTemp, vSubtask, zLEVEL_TASK ); else szTemp[ 0 ] = 0; */ return( szFileName ) ; } public static String GetFocusCtrl( Task task, String szDialog, String szWindow ) { String szDir; String szFileName; String szFileExt; szFileName = null; View vKZXMLPGO = task.getViewByName( WEB_SESSION_VIEW_NAME ); if ( vKZXMLPGO.cursor( "Dialog" ).setFirst( "DialogName", szDialog ).isSet() ) { if ( vKZXMLPGO.cursor( "Window" ).setFirst( "WindowName", szWindow ).isSet() ) { szFileName = vKZXMLPGO.cursor("Window").getAttribute("FocusCtrl").getString(); } } return( szFileName ) ; } public void WriteOiToJson( View view, String filename, int control ) { view.serializeOi().asJson() .setFlags( WriteOiFlags.convertLongFlags( control ) ) .toFile( filename ); } public View ActivateOiFromJson( View view, String filename ) throws Exception { return new DeserializeOi( view ) .asJson() .fromResource( filename ) .activateFirst(); } private final class TextTransfer implements ClipboardOwner { /** * Empty implementation of the ClipboardOwner interface. */ @Override public void lostOwnership( Clipboard aClipboard, Transferable aContents) { // do nothing } /** * Place a String on the clipboard, and make this class the owner of the Clipboard's contents. */ public void setClipboardContents( String str ) { StringSelection stringSelection = new StringSelection( str ); Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); clipboard.setContents( stringSelection, this ); } /** * Get the String residing on the clipboard. * * @return any text found on the Clipboard; if none found, return an empty String. */ public String getClipboardContents() { String result = ""; Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); // odd: the Object param of getContents is not currently used Transferable contents = clipboard.getContents(null); boolean hasTransferableText = (contents != null) && contents.isDataFlavorSupported(DataFlavor.stringFlavor); if ( hasTransferableText ) { try { result = (String)contents.getTransferData(DataFlavor.stringFlavor); } catch (UnsupportedFlavorException ex) { //highly unlikely since we are using a standard DataFlavor System.out.println(ex); ex.printStackTrace(); } catch (IOException ex) { System.out.println(ex); ex.printStackTrace(); } } return result; } } public String SysGetClipboardText( ) { TextTransfer textTransfer = new TextTransfer( ); return textTransfer.getClipboardContents( ); } } /* protected static final char[] g_specialChar = { '<':'<', '>':'>', '&':'&', '"':'"', "'":''', '#':'#', '%':'%' }; public String SysEncodeHTML( String str ) { return str.replace( /[<&>'"#%]/g, function(s) { return g_specialChar[s]; } ); }

            By pressing the button above, a function will be called. The function will alert a message.

            */ // strErrorMapValue = strErrorMapValue.replace("/&/g", "&").replace("/>/g", ">").replace("/