Provides a Java class which represents an SCL list from a remote SAS server. SCL lists are a generic collection data structure provided in the SCL language within with SAS/AF software.

HList (heterogeneous list) objects are used when communicating with the SAS server. HLists are the Java client side analog of SCL lists on the server. If a method of a SAS server object requires an SCL list parameter, the Java client side will suppy an HList. If a method of a SAS server object returns an SCL list, it will be converted to an HList on the Java client side.

This conversion is performed automatically by the proxy facilities provided by com.sas.rmi. Java Interfaces for SAS server objects methods use the Java type `com.sas.collection.hlist.HListInterface` to indicate a parameter or return value that is an SCL list on the SAS server. The HList class is the implementation of this interface.

Key Interfaces
The following are the most important interfaces in the `com.sas.collection.hlist` package:

1. `com.sas.collection.hlist.HListInterface` defines the interface to an `HList` object, which represents an SCL list on a SAS server. An `HList` is an ordered collection of `HListItem`s objects: objects which have a name, a value, and attributes.

Key Classes
The following are the key classes in the `com.sas.collection.hlist` package:

1. ``com.sas.collection.hlist.HList``, The default implementation of the `HListInterface`
2. ``com.sas.collection.hlist.HListItem``, Each item in an HList is an instance of `HListItem`. Specific subclasses of `HListItem` are `DoubleItem`, `StringItem`, `ListItem`, and `ObjectItem`, for storing double, string, lists, and object values respectively.

## SCL List Functions

The Java HList class differs from the SCL list functions because HLists are objects in Java. The tables below will help the developer transfer their knowledge of SCL lists into the corresponding method calls on `HList` objects in Java.

HListInterface extends `com.sas.collection.OrderedCollectionInterface`. Thus, all the ordered collection methods are available. However, `HList` overrides many of the `OrderedCollection` and `Collection` methods and only allows the list to contains items which extend from `HListItem`.

Items in an HList are stored as instances of the `HListItem` class. There are four subclasses: `DoubleItem`, `ListItem`, `ObjectItem`, `StringItem` for holding doubles or missing values, sublists, objects, or String values, respectively. The `HListItem` holds the item's name and item attributes.

Numeric values are stored as doubles. Since Java does not distinguish between different types of NaN values, SAS missing values (_BLANK_, ._, . .A through .Z) are represented in Java with a separate enumeration type, `com.sas.MissingValues` which may appear in `HList DoubleItem` items.

Note that Object values inserted into HLists cannot be transferred into SCL lists on the server.

There is a pattern to how list items are referenced in the methods listed below. For example, the set methods which replace items, the specification of the item position appears first, followed by the value. This is consistent with the scheme used for the collection classes; the easiest way to remember this is to "explode" the array assigment notation:

       array[index] = value;

which maps into

        list.method(position, value);

The container (the array) list listed first, followed by the position, followed by the value to store in the container. For HList, the position can be one of three specifications:

1. int index
2. String name
3. String name, int nth, int startIndex

When reading values from a list, the pattern is reversed:

       value = array[index];

becomes

        value = list.method(position);

where position can be any of the three forms listed above.

There set of list operations are divided into these categories:

1. list creation and management,
2. adding and replacing items in lists
3. deleting items in lists
4. retrieving values from lists,
5. utility functions.

In addition, several SCL list functions are not implemented.

### List Creation and Management

SCL List function | HList method
--- | ---
`MAKELIST` | `HList list = new HList()` `HList list = new HList(int listid)` Note there is no constructor for specifying the initial size, nor is there a way to specify local vs. global lists.
`HASATTR` | `boolean b = list.hasAttribute(HListAttributes attr)` `boolean b = list.hasAttribute(int index, HListAttributes attr)`
`SETLATTR` | `list.setAttribute(HListAttributes attr, boolean state)` `list.setAttribute(int index, HListAttributes attr, boolean state)`

### Adding, Replacing, and Items in Lists

SCL List function | HList method
--- | ---
`INSERTC` | `list.addItem(String string, int index, String name)`
`INSERTL` | `list.addItem(HListInterface list, int index, String name)`
`INSERTN` | `list.addItem(double value, int index, String name)` `list.addItem(MissingValues missingValue, int index, String name)`
`INSERTO` | `list.addItem(Object object, int index, String name)`
`SETITEMC` | `list.setItem(int index, String string)`
`SETITEML` | `list.setItem(int index, HListInterface list)`
`SETITEMN` | `list.setItem(int index, double value)` `list.setItem(int index, MissingValues missingValue)`
`SETITEMO` | `list.setItem(int index, Object object)`
`SETNITEMC` | `list.setItem(String name, String string)` `list.setItem(String name, int nth, int start, String string)`
`SETNITEML` | `list.setItem(String name, HListInterface list)` `list.setItem(String name, int nth, int start, HListInterface list)`
`SETNITEMN` | `list.setItem(String name, double value)` `list.setItem(String name, MissingValues value)` `list.setItem(String name, int nth, int start, double value)` `list.setItem(String name, int nth, int start, MissingValues value)`
`SETNITEMO` | `list.setItem(String name, Object object)` `list.setItem(String name, int nth, int start, Object object)`

### Removing Items in Lists

SCL List function | HList method
--- | ---
`CLEARLIST` | `list.removeAll()` Note: the RECURSIVE or other CLEARLIST options are not supported.
`DELNITEM` | `list.removeAt(String name)` `list.removeAt(String name, int nth, int start)`
`DELITEM` | `list.removeAt(int index)`
`POPC` | `String s = ((StringItem) list.removeAt(0)).getValue()`
`POPL` | `HListInterface l = ((ListItem) list.removeAt(0)).getValue()`
`POPN` | `double s = ((DoubleItem) list.removeAt(0)).getValue()` (item may be a NaN; check Double.isNaN(d). Or, use:
    DoubleItem di = (DoubleItem) list.removeAt(0);
    if (di.isMissing)
       MissingValues m = di.getMissingValue();
    else
       double s = di.getValue();
`POPO` | `Object o = ((ObjectItem) list.removeAt(0)).getValue()`

### Retrieving Values from Lists

SCL List function | HList method
--- | ---
`GETITEMC` | `String s = list.getString(int index)`
`GETITEMN` | `double d = list.getDouble(int index)` d may be a NaN. `MissingValues m = list.getMissingValue(int index)`
`GETITEML` | `HListInterface l = list.getList(int index)`
`GETITEMO` | `Object o = list.getObject(int index)`
`GETNITEMC` | `String s = list.getString(String name)` `String s = list.getString(String name, int nth, int start)`
`GETNITEMN` | `double d = list.getDouble(String name)` `double d = list.getDouble(String name, int nth, int start)` d may be a NaN. `MissingValues m = list.getMissingValue(String name)` `MissingValues m = list.getMissingValue(String name, int nth, int start)`
`GETNITEML` | `HListInterface l = list.getList(String name)` `HListInterface l = list.getList(String name, int nth, int start)`
`GETNITEMO` | `Object o = list.getObject(String name)` `Object o = list.getObject(String name, int nth, int start)`

### Additional Utility functions

SCL List function | HList method
--- | ---
`LISTLEN` | `int length = list.count()`
`NAMEDITEM` | `int index = list.find(String name, int nth, int start)`
`NAMEITEM` | String name = list.getItem(int index).`getName()` list.getItem(int index).`setName(String name)`
`PUTLIST` | `list.print(PrintWriter pw)`
`REVLIST` | `list.reverse()`
`ROTLIST` | `list.rotate(int count)`
`SORTLIST` | `list.sort(Comparator comparator)` `list.sort(Comparator comparator, int start, int end)` You must supply a Comparator which compares two HListItems according to your comparison criteria.

### Unimplemented functions

Some SCL lists functions do not have equivalent methods in the Java HList implementation. These functions are:

SCL List function | HList method
--- | ---
`COPYLIST` | HList inherts from OrderedCollection which has a public clone() method, but this method only clones the collection, not the items in the collection. HList items are also clonable.
`CURLIST` | No equivalent method
`DELLIST` | Not necessary; Java has garbage collection
`ENVLIST` | No equivalent method
`FILLIST` | The `read(java.io.DataInputStream stream)` method can read a list from a byte stream created by the `write(java.io.DataOutputStream stream)`. Also, `HList` implements `java.io.Serializable`, so you can serialize `HList` objects.
`ITEMTYPE` |
`MAKENLIST` | No equivalent method
`POPMENU` | No equivalent method
`SAVELIST` | `list.write(DataOutputStream stream)` saves an `HList` and its sublists to a `DataOutputStream`.
`SEARCHC` | No equivalent method. It is possible to create an object implementing `com.sas.util.PredicateInterface` which does item comparisons and keeps track of item counts.
`SEARCHN` | No equivalent method, but see `SEARCHC` above
`SEARCHL` | No equivalent method, but see `SEARCHC` above
`SEARCHO` | No equivalent method, but see `SEARCHC` above

## Differences from SCL List Functions

`HList`, like Java arrays, `Vector`s, and `OrderedCollection`s, are zero based. Thus, the first item in an `HList` is at index 0. The last item is at index `list.count()-1`. You can still use an index of -1 to insert an item at the end of an `HList`.

The `HList` class does not use return codes to indicate error conditions. Instead, the methods will throw Java exceptions when errors are enountered. For example, attempting to store an item in a list at an index greater than the list size will result in an `IndexOutOfBoundsException`.

The `HList` class does not enforce the list and item attributes, but probably will in a future release.