[Swift-commit] r7839 - in trunk/src/org/griphyn/vdl/mapping: . file nodes

hategan at ci.uchicago.edu hategan at ci.uchicago.edu
Thu May 8 23:35:05 CDT 2014


Author: hategan
Date: 2014-05-08 23:35:05 -0500 (Thu, 08 May 2014)
New Revision: 7839

Added:
   trunk/src/org/griphyn/vdl/mapping/nodes/
   trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedArrayDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedMappedSingleDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedNonCompositeDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedPrimitiveDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedStructDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/AbstractDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureArrayDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureMappedSingleDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureNonCompositeDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFuturePrimitiveDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureStructDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/ArrayHandle.java
   trunk/src/org/griphyn/vdl/mapping/nodes/ClosedArrayDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/ClosedMappedSingleDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/ClosedPrimitiveDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/ExternalDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/FutureArrayDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/FutureMappedSingleDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/FuturePrimitiveDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/FutureStructDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/InitMapper.java
   trunk/src/org/griphyn/vdl/mapping/nodes/NodeFactory.java
   trunk/src/org/griphyn/vdl/mapping/nodes/RootClosedArrayDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/RootClosedMappedSingleDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/RootClosedPrimitiveDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/RootFutureArrayDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/RootFutureMappedSingleDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/RootFuturePrimitiveDataNode.java
   trunk/src/org/griphyn/vdl/mapping/nodes/RootFutureStructDataNode.java
Removed:
   trunk/src/org/griphyn/vdl/mapping/AbstractDataNode.java
   trunk/src/org/griphyn/vdl/mapping/ArrayDataNode.java
   trunk/src/org/griphyn/vdl/mapping/DataNode.java
   trunk/src/org/griphyn/vdl/mapping/ExternalDataNode.java
   trunk/src/org/griphyn/vdl/mapping/RootArrayDataNode.java
   trunk/src/org/griphyn/vdl/mapping/RootDataNode.java
Modified:
   trunk/src/org/griphyn/vdl/mapping/AbstractMapper.java
   trunk/src/org/griphyn/vdl/mapping/DSHandle.java
   trunk/src/org/griphyn/vdl/mapping/DependentException.java
   trunk/src/org/griphyn/vdl/mapping/DuplicateMappingChecker.java
   trunk/src/org/griphyn/vdl/mapping/InvalidPathException.java
   trunk/src/org/griphyn/vdl/mapping/Mapper.java
   trunk/src/org/griphyn/vdl/mapping/MappingParamSet.java
   trunk/src/org/griphyn/vdl/mapping/MissingDataException.java
   trunk/src/org/griphyn/vdl/mapping/NotCompositeException.java
   trunk/src/org/griphyn/vdl/mapping/NullMapper.java
   trunk/src/org/griphyn/vdl/mapping/OpenArrayEntries.java
   trunk/src/org/griphyn/vdl/mapping/Path.java
   trunk/src/org/griphyn/vdl/mapping/RootHandle.java
   trunk/src/org/griphyn/vdl/mapping/file/AbstractFileMapperParams.java
   trunk/src/org/griphyn/vdl/mapping/file/ArrayFileMapperParams.java
   trunk/src/org/griphyn/vdl/mapping/file/CSVMapperParams.java
   trunk/src/org/griphyn/vdl/mapping/file/ExternalMapperParams.java
   trunk/src/org/griphyn/vdl/mapping/file/FixedArrayFileMapperParams.java
   trunk/src/org/griphyn/vdl/mapping/file/MappingParamFileGenerator.java
   trunk/src/org/griphyn/vdl/mapping/file/RegularExpressionMapperParams.java
   trunk/src/org/griphyn/vdl/mapping/file/SimpleFileMapperParams.java
   trunk/src/org/griphyn/vdl/mapping/file/SingleFileMapperParams.java
   trunk/src/org/griphyn/vdl/mapping/file/StructuredRegularExpressionMapper.java
   trunk/src/org/griphyn/vdl/mapping/file/StructuredRegularExpressionMapperParams.java
   trunk/src/org/griphyn/vdl/mapping/file/TestMapperParams.java
Log:
re-organized the data node business in a more OO-proper way (though this is one place where multiple inheritance would be good)

Deleted: trunk/src/org/griphyn/vdl/mapping/AbstractDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/AbstractDataNode.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/AbstractDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -1,843 +0,0 @@
-/*
- * Copyright 2012 University of Chicago
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/*
- * Created on Jun 6, 2006
- */
-package org.griphyn.vdl.mapping;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import k.rt.FutureListener;
-import k.rt.FutureValue;
-import k.thr.Yield;
-
-import org.apache.log4j.Logger;
-import org.globus.cog.karajan.compiled.nodes.Node;
-import org.globus.cog.karajan.futures.FutureNotYetAvailable;
-import org.griphyn.vdl.karajan.Loader;
-import org.griphyn.vdl.karajan.WaitingThreadsMonitor;
-import org.griphyn.vdl.karajan.lib.Tracer;
-import org.griphyn.vdl.type.Field;
-import org.griphyn.vdl.type.Type;
-import org.griphyn.vdl.util.VDL2Config;
-
-
-
-public abstract class AbstractDataNode implements DSHandle, FutureValue {
-    public static final Object FILE_VALUE = new Object() {
-        public String toString() {
-            return "<FILE>";
-        }
-    };
-
-    static final String DATASET_URI_PREFIX = "dataset:";
-
-    public static final Logger logger = Logger.getLogger(AbstractDataNode.class);
-
-    /**
-     * Datasets are identified within a run by this sequence number and the
-     * partial ID field. The initial value is chosen to aid human recognition of
-     * sequence numbers in the wild. There is no requirement that it start at
-     * this (or any other) particular value. Note that this introduces a maximum
-     * on the number of datasets which can be dealt with in any run to be about
-     * 2^62.
-     */
-    private static long datasetIDCounter = 720000000000l;
-
-    /**
-     * This is used to provide a (hopefully) globally unique identifier for each
-     * time the datasetIDCounter is reset (whenever this class is loaded, which
-     * will usually happen once per JVM). No meaning should be inferred from
-     * this value - it exists purely for making unique URIs.
-     */
-    private static final String datasetIDPartialID = Loader.getUUID();
-    
-    public static boolean provenance = false;
-    static {
-        try {
-        	provenance = VDL2Config.getConfig().getProvenanceLog();
-        }
-        catch (IOException e) {
-        }
-    }
-    
-    private Field field;
-    private Map<Comparable<?>, DSHandle> handles;
-    private Object value;
-    private boolean closed;
-    private String identifier;
-    private Path pathFromRoot;
-    
-    private int writeRefCount;
-    private List<FutureListener> listeners;
-        
-    protected static final Tracer variableTracer = Tracer.getTracer("VARIABLE");
-
-    protected AbstractDataNode(Field field) {
-        this.field = field;
-        if (field.getType().isComposite()) {
-            handles = new HashMap<Comparable<?>, DSHandle>();
-        }
-        else {
-            handles = Collections.emptyMap();
-        }
-    }
-
-    protected void populateStructFields() {
-        for (String name : getType().getFieldNames()) {
-            try {
-                createField(name);
-            }
-            catch (NoSuchFieldException e) {
-                throw new RuntimeException("Internal inconsistency found: field '" + name 
-                    + "' is listed by the type but createField() claims it is invalid");
-            }
-        }
-    }
-    
-    public String getName() {
-        return getRoot().getName();
-    }
-    
-    @Override
-    public void setName(String name) {
-        throw new UnsupportedOperationException("setName can only be called on a root variable");
-    }
-    
-    public Type getType() {
-        return field.getType();
-    }
-
-    public boolean isPrimitive() {
-        return field.getType().isPrimitive();
-    }
-
-    public boolean isRestartable() {
-        return !isPrimitive();
-    }
-
-    protected Field getField() {
-        return field;
-    }
-    
-    protected abstract AbstractDataNode getParentNode();
-
-    /**
-     * create a String representation of this node. If the node has a value,
-     * then uses the String representation of that value. Otherwise, generates a
-     * text description.
-     */
-    public String toString() {
-        return toDisplayableString();
-    }
-
-    private String toDisplayableString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append(getDisplayableName());
-        Path p = getPathFromRoot();
-        if (!p.isEmpty()) {
-            if (!p.isArrayIndex(0)) {
-                sb.append(".");
-            }
-            sb.append(p.toString());
-        }
-        sb.append(":");
-        Type type = getType();
-        String strtype = type.toString();
-        if (type.isArray() && closed) {
-            strtype = strtype.replace("[]", "[" + this.getHandles().size() + "]");
-        }
-        sb.append(strtype);
-        if (value != null) {
-            sb.append(" = ");
-            if (value instanceof Throwable) {
-                sb.append(value.getClass().getName());
-            }
-            else {
-                sb.append(value);
-            }
-        }
-        if (closed) {
-            sb.append(" - Closed");
-        }
-        else {
-            sb.append(" - Open");
-        }
-        return sb.toString();
-    }
-
-    public String getIdentifyingString() {
-        StringBuffer sb = new StringBuffer();
-        sb.append(this.getClass().getName());
-
-        sb.append(" identifier ");
-        sb.append(this.getIdentifier());
-
-        sb.append(" type ");
-        sb.append(getType());
-
-        if (value == null) {
-            sb.append(" with no value at dataset=");
-        }
-        else if (value instanceof Throwable) {
-            sb.append(" containing throwable ");
-            sb.append(value.getClass());
-            sb.append(" dataset=");
-        }
-        else {
-            sb.append(" value=");
-            sb.append(this.value.toString());
-            sb.append(" dataset=");
-        }
-
-        sb.append(getDisplayableName());
-
-        if (!Path.EMPTY_PATH.equals(getPathFromRoot())) {
-            sb.append(" path=");
-            sb.append(getPathFromRoot().toString());
-        }
-
-        if (closed) {
-            sb.append(" (closed)");
-        }
-        else {
-            sb.append(" (not closed)");
-        }
-
-        return sb.toString();
-    }
-
-    public String getDisplayableName() {
-        return getName();
-    }
-    
-    public String getFullName() {
-        String name = getDisplayableName();
-        Path p = getPathFromRoot();
-        if (p.isEmpty()) {
-            return name;
-        }
-        else {
-            return name + "." + p;
-        }
-    }
-
-    public DSHandle getField(Path path) throws InvalidPathException {
-        if (path.isEmpty()) {
-            return this;
-        }
-        try {
-            DSHandle handle = getField(path.getFirst());
-            
-            if (path.size() > 1) {
-                return handle.getField(path.butFirst());
-            }
-            else {
-                return handle;
-            }
-        }
-        catch (NoSuchFieldException e) {
-            throw new InvalidPathException(path, this);
-        }
-    }
-
-    public Collection<DSHandle> getFields(Path path) throws InvalidPathException {
-        List<DSHandle> fields = new ArrayList<DSHandle>();
-        getFields(fields, path);
-        return fields;
-    }
-
-    protected void getFields(List<DSHandle> fields, Path path) throws InvalidPathException {
-        if (path.isEmpty()) {
-            fields.add(this);
-        }
-        else {
-            if (path.isWildcard(0)) {
-                throw new InvalidPathException("getFields([*]) only applies to arrays");
-            }
-            try {
-                ((AbstractDataNode) getField(path.getFirst())).getFields(fields, path.butFirst());
-            }
-            catch (NoSuchFieldException e) {
-                throw new InvalidPathException(path, this);
-            }
-        }
-    }
-
-    public void set(DSHandle handle) {
-        // TODO check type
-        if (closed) {
-            throw new IllegalArgumentException(this.getDisplayableName() + " is already assigned");
-        }
-        if (getParent() == null) {
-            /*
-             * AbstractDataNode node = (AbstractDataNode)handle; field =
-             * node.getField(); handles = node.getHandles(); closed =
-             * node.isClosed(); value = node.getValue();
-             */
-            throw new RuntimeException("Can't set root data node!");
-        }
-        ((AbstractDataNode) getParent()).setField(field.getId(), handle);
-    }
-
-    protected synchronized void setField(Comparable<?> id, DSHandle handle) {
-        handles.put(id, handle);
-    }
-
-    public synchronized DSHandle getField(Comparable<?> key) throws NoSuchFieldException {
-        DSHandle handle = handles.get(key);
-        if (handle == null) {
-            if (closed) {
-                throw new NoSuchFieldException(key.toString());
-            }
-            handle = createField(key);
-        }
-        return handle;
-    }
-
-    protected synchronized boolean isHandlesEmpty() {
-        return handles.isEmpty();
-    }
-
-    public DSHandle createField(Comparable<?> key) throws NoSuchFieldException {
-        if (closed) {
-            throw new RuntimeException("Cannot write to closed handle: " + this + " (" + key + ")");
-        }
-        
-        if (!getType().isComposite()) {
-            throw new NotCompositeException(this);
-        }
-        
-        return addHandle(key, newNode(getChildField(key)));
-    }
-    
-    @Override
-    public DSHandle createField(Path path) throws InvalidPathException {
-        if (path.size() != 1) {
-            throw new InvalidPathException("Expected a path of size 1: " + path);
-        }
-        try {
-            return createField(path.getFirst());
-        }
-        catch (NoSuchFieldException e) {
-            throw new InvalidPathException("Invalid path (" + path + ") for " + this);
-        }
-    }
-
-    protected synchronized DSHandle addHandle(Comparable<?> id, DSHandle handle) {
-        Object o = handles.put(id, handle);
-        if (o != null) {
-            throw new RuntimeException("Trying to create a handle that already exists (" + id + ") in " + this);
-        }
-        return handle;
-    }
-    
-    protected AbstractDataNode newNode(Field f) {
-        if (f.getType().isArray()) {
-            return new ArrayDataNode(f, getRoot(), this);
-        }
-        else {
-            DataNode dn = new DataNode(f, getRoot(), this);
-            if (field.getType().isComposite()) {
-                dn.populateStructFields();
-            }
-            return dn;
-        }
-    }
-        
-    protected Field getChildField(Comparable<?> key) throws NoSuchFieldException {
-        if (getType().isArray()) {
-            return Field.Factory.createField(key, getType().itemType());
-        }
-        else {
-            return Field.Factory.getImmutableField(key, getType().getField((String) key).getType());
-        }
-    }
-    
-    protected Field getArrayChildField(Comparable<?> key) {
-        return Field.Factory.createField(key, getType().itemType());
-    }
-
-    protected void checkDataException() {
-        if (value instanceof DependentException) {
-            throw (DependentException) value;
-        }
-    }
-
-    protected void checkMappingException() {
-        if (value instanceof MappingDependentException) {
-            throw (MappingDependentException) value;
-        }
-    }
-
-    public synchronized Object getValue() {
-        checkNoValue();
-        checkDataException();
-        if (field.getType().isArray()) {
-            return handles;
-        }
-        return value;
-    }
-
-    public Map<Comparable<?>, DSHandle> getArrayValue() {
-        checkDataException();
-        if (!field.getType().isArray()) {
-            throw new RuntimeException("getArrayValue called on a non-array: " + this);
-        }
-        return handles;
-    }
-
-    public boolean isArray() {
-        return false;
-    }
-
-    public void setValue(Object value) {
-        synchronized(this) {
-            if (this.closed) {
-                throw new IllegalArgumentException(this.getFullName() 
-                		+ " is closed with a value of " + this.value);
-            }
-            if (this.value != null) {
-                throw new IllegalArgumentException(this.getFullName() 
-                		+ " is already assigned with a value of " + this.value);
-            }
-        
-            this.value = value;
-            this.closed = true;
-        }
-        postCloseActions();
-    }
-
-    public Collection<Path> getFringePaths() throws HandleOpenException {
-        List<Path> list = new ArrayList<Path>();
-        getFringePaths(list, Path.EMPTY_PATH);
-        return list;
-    }
-    
-    public void getFringePaths(List<Path> list, Path parentPath)
-    throws HandleOpenException {
-        checkMappingException();
-        if (getType().getBaseType() != null) {
-            list.add(Path.EMPTY_PATH);
-        }
-        else {
-            for (Field field : getType().getFields()) {
-                AbstractDataNode child;
-                String name = (String) field.getId();
-                try {
-                    child = (AbstractDataNode) this.getField(name);
-                }
-                catch (NoSuchFieldException e) {
-                    throw new RuntimeException("Inconsistency between type declaration and " + 
-                        "handle for field '" + name + "'");
-                }
-                Path fullPath = parentPath.addLast(name);
-                Type type = child.getType(); 
-                if (!type.isPrimitive() && !child.isArray() && type.getFields().size() == 0) {
-                    list.add(fullPath);
-                }
-                else {
-                    child.getFringePaths(list, fullPath);
-                }
-            }
-        }
-    }
-    
-    public Collection<DSHandle> getLeaves() throws HandleOpenException {
-        Type t = getType();
-        if (t.isPrimitive()) {
-            return Collections.emptyList();
-        }
-        if (!t.isComposite()) {
-            return Collections.singletonList((DSHandle) this);
-        }
-        List<DSHandle> list = new ArrayList<DSHandle>();
-        getLeaves(list);
-        return list;
-    }
-    
-    public void getLeaves(List<DSHandle> list) throws HandleOpenException {
-        checkMappingException();
-        if (getType().getBaseType() != null) {
-            list.add(this);
-        }
-        else {
-            for (Field field : getType().getFields()) {
-                AbstractDataNode child;
-                String name = (String) field.getId();
-                try {
-                    child = (AbstractDataNode) this.getField(name);
-                }
-                catch (NoSuchFieldException e) {
-                    throw new RuntimeException("Inconsistency between type declaration and " + 
-                        "handle for field '" + name + "'");
-                }
-                Type type = child.getType(); 
-                if (!type.isPrimitive() && !child.isArray() && type.getFields().size() == 0) {
-                    list.add(child);
-                }
-                else {
-                    child.getLeaves(list);
-                }
-            }
-        }
-    }
-        
-    public void closeShallow() {
-        synchronized(this) {
-            if (this.closed) {
-                return;
-            }
-            this.closed = true;
-        }
-        postCloseActions();
-    }
-
-    private void postCloseActions() {
-        // closed
-        notifyListeners();
-        if (logger.isDebugEnabled()) {
-            logger.debug("closed " + this.getIdentifyingString());
-        }
-        // so because its closed, we can dump the contents
-
-        try {
-            if(provenance) {
-                logContent();
-            }
-        }
-        catch (Exception e) {
-            logger.warn("Exception whilst logging dataset content for " + this, e);
-        }
-        // TODO record retrospective provenance information for this dataset here
-        // we should do it at closing time because that's the point at which we
-        // know the dataset has its values (all the way down the tree) assigned.
-
-        // provenance-id for this dataset should have been assigned at creation time,
-        // though, so that we can refer to this dataset elsewhere before it is closed.
-
-        // is this method the only one called to set this.closed? or do subclasses
-        // or other methods ever change it?
-    }
-
-    public synchronized void logContent() {
-        String identifier = this.getIdentifier();
-        Path pathFromRoot = this.getPathFromRoot();
-        if (this.getPathFromRoot() != null) {
-            if (logger.isInfoEnabled()) {
-                logger.info("ROOTPATH dataset=" + identifier + " path=" + pathFromRoot);
-                if (this.getType().isPrimitive()) {
-                    logger.info("VALUE dataset=" + identifier + " VALUE=" + this.toString());
-                }
-            }
-
-            Mapper m = getActualMapper();
-
-
-            if (m != null) {
-                // TODO proper type here
-                // Not sure catching exception here is really the right thing to
-                // do here
-                // anyway - should perhaps only be trying to map leafnodes?
-                // Mapping
-                // non-leaf stuff is giving wierd paths anyway
-
-                // TODO this is perhaps an unpleasant way of finding if this is a file-backed
-                // leaf node or not
-                boolean filemapped = true;
-                Type type = this.getType();
-                if(type.getName().equals("external")) {
-                    filemapped = false;
-                }
-                if(type.isPrimitive()) {
-                    filemapped = false;
-                }
-                if(type.isArray()) {
-                    filemapped = false;
-                }
-                if(handles.size()>0) {
-                    filemapped = false;
-                }
-
-                try {
-                    if (filemapped) {
-                        Object path = map();
-                        if (logger.isInfoEnabled()) {
-                            logger.info("FILENAME dataset=" + identifier + " filename=" + path);
-                        }
-                    }
-                }
-                catch (Exception e) {
-                    if (logger.isInfoEnabled()) {
-                        logger.info("NOFILENAME dataset=" + identifier);
-                    }
-                }
-            }
-        }
-
-        synchronized (this) {
-            //Iterator i = handles.entrySet().iterator();
-            //while (i.hasNext()) {
-            //    Map.Entry e = (Map.Entry) i.next();
-            for (DSHandle handle : handles.values()) {
-                AbstractDataNode node = (AbstractDataNode) handle;
-                if (logger.isInfoEnabled()) {
-                    logger.info("CONTAINMENT parent=" + identifier + " child=" + node.getIdentifier());
-                }
-                node.logContent();
-            }
-        }
-    }
-    
-    public Mapper getActualMapper() {
-        return null;
-    }
-
-    public boolean isClosed() {
-        return closed;
-    }
-
-    public synchronized void closeDeep() {
-        if (!this.closed) {
-            closeShallow();
-        }
-        for (DSHandle handle : handles.values()) {
-            AbstractDataNode mapper = (AbstractDataNode) handle;
-            mapper.closeDeep();
-        }
-    }
-	
-	/**
-     * Recursively closes arrays through a tree of arrays and complex types.
-     */
-    public void closeArraySizes() {
-        if (!this.closed && this.getType().isArray()) {
-            closeShallow();
-        }
-        synchronized (this) {
-            for (DSHandle handle : handles.values()) {
-                AbstractDataNode child = (AbstractDataNode) handle;
-                if (child.getType().isArray() || child.getType().getFields().size() > 0) {
-                    child.closeArraySizes();
-                }
-            }
-        }
-    }
-    
-    public Path getPathFromRoot() {
-        if (pathFromRoot == null) {
-            AbstractDataNode parent = (AbstractDataNode) this.getParent();
-            Path myPath;
-            if (parent != null) {
-                myPath = parent.getPathFromRoot();
-                pathFromRoot = myPath.addLast(getField().getId(), parent.getField().getType().isArray());
-            }
-            else {
-                pathFromRoot = Path.EMPTY_PATH;
-            }
-        }
-        return pathFromRoot;
-    }
-
-    public Mapper getMapper() {
-        return ((AbstractDataNode) getRoot()).getMapper();
-    }
-    
-    @Override
-    public PhysicalFormat map(Path path) {
-        Mapper m = getMapper();
-        if (m == null) {
-            return null;
-        }
-        else {
-            Path p = getPathFromRoot().append(path);
-            return m.map(p);
-        }
-    }
-
-    @Override
-    public PhysicalFormat map() {
-        return map(Path.EMPTY_PATH);
-    }
-
-    protected Map<Comparable<?>, DSHandle> getHandles() {
-        return handles;
-    }
-    
-    public synchronized String getIdentifier() {
-    	if (identifier == null) {
-   		    identifier = makeIdentifierURIString();
-    	}
-        return identifier;
-    }
-
-    String makeIdentifierURIString() {
-        datasetIDCounter++;
-        return DATASET_URI_PREFIX + datasetIDPartialID + ":" + datasetIDCounter;
-    }
-       
-    public synchronized void waitFor(Node who) {
-        if (!closed) {
-            if (logger.isDebugEnabled()) {
-                logger.debug("Waiting for " + this);
-            }
-            
-            Yield y = new FutureNotYetAvailable(this);
-            y.getState().addTraceElement(who);
-            throw y;
-        }
-        else {
-            if (logger.isDebugEnabled()) {
-                logger.debug("Do not need to wait for " + this);
-            }
-            checkNoValue();
-            if (value instanceof RuntimeException) {
-                throw (RuntimeException) value;
-            }
-        }
-    }
-    
-    public synchronized void waitFor() throws OOBYield {
-        if (!closed) {
-            if (logger.isDebugEnabled()) {
-                logger.debug("Waiting for " + this);
-            }
-            
-            throw new OOBYield(new FutureNotYetAvailable(this), this);
-        }
-        else {
-            if (logger.isDebugEnabled()) {
-                logger.debug("Do not need to wait for " + this);
-            }
-            checkNoValue();
-            if (value instanceof RuntimeException) {
-                throw (RuntimeException) value;
-            }
-        }
-    }
-    
-    protected void checkNoValue() {
-        if (value == null) {
-            if (getType().isComposite()) {
-                // composite types (arrays, structs) don't usually have a value
-                return;
-            }
-            AbstractDataNode parent = getParentNode();
-            if (parent != null && parent.getType().isArray()) {
-                throw new IndexOutOfBoundsException("Invalid index [" + field.getId() + "] for " + parent.getFullName());
-            }
-            else if (getType().isPrimitive()) {
-                throw new RuntimeException(getFullName() + " has no value");
-            }
-            else {
-                throw new MissingDataException(this, map());
-            }
-        }
-    }
-
-    public void addListener(DSHandleListener listener) {
-        throw new UnsupportedOperationException();
-    }
-    
-    public void addListener(FutureListener l) {
-        addListener(l, true);
-    }
-    
-    public void addListener(FutureListener l, boolean partialUpdates) {
-    	boolean closed;
-    	WaitingThreadsMonitor.addThread(l, this);
-    	synchronized(this) {
-    	    closed = addListener0(l);
-    	}
-    	if (closed) {
-    		notifyListeners();
-    	}
-    }
-    
-    protected boolean addListener0(FutureListener l) {
-        if (this.listeners == null) {
-            this.listeners = new ArrayList<FutureListener>();
-        }
-        this.listeners.add(l);
-        return this.closed;
-    }
-        
-    protected void notifyListeners() {
-    	List<FutureListener> l;
-    	synchronized(this) {
-    		l = this.listeners;
-    		this.listeners = null;
-    	}
-    	if (l != null) {
-    		for (FutureListener ll : l) {
-    			ll.futureUpdated(this);
-    			WaitingThreadsMonitor.removeThread(ll);
-    		}
-    	}
-    }
-
-    public synchronized void clean() {
-        if (!handles.isEmpty()) {
-            for (DSHandle h : handles.values()) {
-                ((AbstractDataNode) h).clean();
-            }
-        }
-        else if (!getType().isArray() && !getType().isPrimitive()) {
-            Mapper mapper = getMapper();
-            if (mapper != null) {
-                mapper.clean(getPathFromRoot());
-            }
-        }
-        field = null;
-        handles = null;
-        value = null;
-        pathFromRoot = null;
-    }
-
-    @Override
-    public synchronized void setWriteRefCount(int count) {
-        this.writeRefCount = count;
-    }
-
-    @Override
-    public synchronized int updateWriteRefCount(int delta) {
-        this.writeRefCount += delta;
-       
-        if (this.writeRefCount < 0) {
-            throw new IllegalArgumentException("Reference count mismatch for " + this + ". Count is " + this.writeRefCount);
-        }
-                        
-        if (logger.isDebugEnabled()) {
-            logger.debug(this + " writeRefCount " + this.writeRefCount);
-        }
-        if (this.writeRefCount == 0) {
-            if (variableTracer.isEnabled()) {
-                RootHandle root = getRoot();
-                variableTracer.trace(root.getThread(), root.getLine(), getDisplayableName() + " CLOSE write ref count is zero");
-            }
-            closeDeep();
-        }
-        return this.writeRefCount;
-    }
-}

Modified: trunk/src/org/griphyn/vdl/mapping/AbstractMapper.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/AbstractMapper.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/AbstractMapper.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -24,6 +24,7 @@
 
 import org.apache.log4j.Logger;
 import org.griphyn.vdl.mapping.file.FileGarbageCollector;
+import org.griphyn.vdl.mapping.nodes.AbstractDataNode;
 import org.griphyn.vdl.type.Type;
 
 /** AbstractMapper provides an implementation of the Mapper interface to be

Deleted: trunk/src/org/griphyn/vdl/mapping/ArrayDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/ArrayDataNode.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/ArrayDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -1,196 +0,0 @@
-/*
- * Copyright 2012 University of Chicago
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/*
- * Created on Jun 30, 2006
- */
-package org.griphyn.vdl.mapping;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import k.rt.FutureListener;
-
-import org.globus.cog.karajan.futures.FutureNotYetAvailable;
-import org.griphyn.vdl.karajan.WaitingThreadsMonitor;
-import org.griphyn.vdl.type.Field;
-
-public class ArrayDataNode extends DataNode { 
-    
-	private List<Comparable<?>> keyList;
-	
-	protected ArrayDataNode(Field field, RootHandle root, AbstractDataNode parent) {
-		super(field, root, parent);
-	}
-	
-	public void getFringePaths(List<Path> list, Path parentPath) throws HandleOpenException {
-		checkMappingException();
-		if (!isClosed()) {
-		    throw new FutureNotYetAvailable(this);
-		}
-		Map<Comparable<?>, DSHandle> handles = getHandles();
-		synchronized (this) {
-			for (Map.Entry<Comparable<?>, DSHandle> e : handles.entrySet()) {
-				AbstractDataNode mapper = (AbstractDataNode) e.getValue();
-				Path fullPath = parentPath.addLast(e.getKey(), getType().isArray());
-				if (mapper.getType().isComposite()) {
-					mapper.getFringePaths(list, fullPath);
-				}
-				else if (!mapper.getType().isPrimitive()) {
-					list.add(fullPath);
-				}
-			}
-		}
-	}
-	
-	/**
-	 * Get leaves and make sure they are sorted based on the indices
-	 */
-	public void getLeaves(List<DSHandle> list) throws HandleOpenException {
-        checkMappingException();
-        if (!isClosed()) {
-            throw new HandleOpenException(this);
-        }
-        Map<Comparable<?>, DSHandle> handles = getHandles();
-        Collection<DSHandle> values = handles.values();
-        for (DSHandle child : values) {
-            ((AbstractDataNode) child).getLeaves(list);
-        }
-    }
-	
-	/** Recursively closes arrays through a tree of arrays and complex
-        types. */
-    public void closeDeep() {
-        assert(this.getType().isArray());
-        closeShallow();
-        Map<Comparable<?>, DSHandle> handles = getHandles();
-        synchronized (this) {
-        	for (Map.Entry<Comparable<?>, DSHandle> e : handles.entrySet()) {
-                AbstractDataNode child = (AbstractDataNode) e.getValue();
-                child.closeDeep();
-            }
-        }
-    }
-	
-	public boolean isArray() {
-		return true;
-	}
-	
-	public int size() {
-		return getHandles().size();
-	}
-	
-    @Override
-    protected void setField(Comparable<?> id, DSHandle handle) {
-        synchronized(this) {
-            super.setField(id, handle);
-            // Operations on the handles and the wrapper keys need to be synchronized.
-            // When a wrapper is created, it populates its list of keys with the handles
-            // available. If this happens concurrently with a call being exactly at this
-            // point in the code, then it's possible for a key to have both been added
-            // as part of the creation of the wrapper as well as due to the next call,
-            // causing duplicate iterations.
-            addKey(id);
-        }
-    }
-    
-    private void addKey(Comparable<?> key) {
-    	synchronized(this) {
-    		if (keyList != null) {
-    			keyList.add(key);
-    		}
-    	}
-        notifyListeners();
-    }
-    
-    @Override
-    public void addListener(FutureListener l, boolean partialUpdates) {
-        boolean shouldNotify;
-        WaitingThreadsMonitor.addThread(l, this);
-        synchronized(this) {
-            shouldNotify = addListener0(l);
-            if (keyList != null && partialUpdates) {
-                shouldNotify = true;
-            }
-        }
-        if (shouldNotify) {
-            notifyListeners();
-        }
-    }
-
-    @Override
-    public synchronized DSHandle createField(Comparable<?> key) throws NoSuchFieldException {
-        DSHandle h = super.createField(key);
-        addKey(key);
-        return h;
-    }
-    
-    public Iterable<List<?>> entryList() {
-    	synchronized(this) {
-    		if (isClosed()) {
-    			return new ClosedArrayEntries(getArrayValue());
-    		}
-    		else {
-    			keyList = new ArrayList<Comparable<?>>(getArrayValue().keySet());
-    			return new OpenArrayEntries(keyList, getArrayValue(), this);
-    		}
-    	}
-    }
-    
-    @Override
-    public void closeShallow() {
-        super.closeShallow();
-        synchronized(this) {
-        	keyList = null;
-        }
-    }
-
-    protected void getFields(List<DSHandle> fields, Path path) throws InvalidPathException {
-        if (path.isEmpty()) {
-            fields.add(this);
-        }
-        else {
-            Path rest = path.butFirst();
-            if (path.isWildcard(0)) {
-                if (!isClosed()) {
-                    throw new FutureNotYetAvailable(this);
-                }
-                for (DSHandle handle : getHandles().values()) {
-                    ((AbstractDataNode) handle).getFields(fields, rest);
-                }
-            }
-            else {
-                try {
-                    ((AbstractDataNode) getField(path.getKey(0))).getFields(
-                        fields, path.butFirst());
-                }
-                catch (NoSuchFieldException e) {
-                    throw new InvalidPathException(path.getKey(0), this);
-                }
-            }
-        }
-    }
-
-    @Override
-    protected void checkNoValue() {
-        // lack of a value in an array node does not indicate an error
-    }
-    
-    
-}

Modified: trunk/src/org/griphyn/vdl/mapping/DSHandle.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/DSHandle.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/DSHandle.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -71,17 +71,12 @@
      *
      *  @return a Collection of DSHandle objects
      */
-    public Collection<DSHandle> getFields(Path path) throws InvalidPathException, HandleOpenException;
+    public Collection<DSHandle> getAllFields() throws InvalidPathException, HandleOpenException;
 
     public Object getValue();
 
     public void setValue(Object value);
-
-    /** create a new logical component */
-    public DSHandle createField(Comparable<?> key) throws NoSuchFieldException;
  
-    public DSHandle createField(Path path) throws InvalidPathException;
- 
     // special file oriented methods, not sure if these apply to 
     // all datasets
 
@@ -98,8 +93,6 @@
 
     public Path getPathFromRoot();
 
-    public void set(DSHandle svar);
-
     public boolean isClosed();
 
     public void addListener(DSHandleListener listener);

Deleted: trunk/src/org/griphyn/vdl/mapping/DataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/DataNode.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/DataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -1,54 +0,0 @@
-/*
- * Copyright 2012 University of Chicago
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/*
- * Created on Jun 15, 2006
- */
-package org.griphyn.vdl.mapping;
-
-import org.griphyn.vdl.type.Field;
-
-
-public class DataNode extends AbstractDataNode {
-	private RootHandle root;
-	private AbstractDataNode parent;
-	
-	protected DataNode(Field field, RootHandle root, AbstractDataNode parent) {
-		super(field);
-		if (parent != null && field.getId() == null) {
-		    throw new IllegalArgumentException("Internal error: field id is null");
-		}
-		this.root = root;
-		this.parent = parent;
-	}
-	
-	public RootHandle getRoot() {
-		return root;
-	}
-	
-	public DSHandle getParent() {
-		return parent;
-	}
-	
-	public AbstractDataNode getParentNode() {
-        return parent;
-    }
-	
-	public void setParent(AbstractDataNode parent) {
-		this.parent = parent;
-	}
-}

Modified: trunk/src/org/griphyn/vdl/mapping/DependentException.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/DependentException.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/DependentException.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -25,10 +25,13 @@
  */
 public abstract class DependentException extends RuntimeException {
 	private DSHandle handle;
+	private String name;
 
 	public DependentException(DSHandle handle, Exception prev) {
 		super(prev);
 		this.handle = handle;
+		// store the name here since it might get set to null during handle.cleanup()
+		this.name = handle.getRoot().getName();
 	}
 
 	public DependentException(DSHandle handle) {
@@ -44,7 +47,7 @@
 	
 	public String getVariableInfo() {
 	    RootHandle root = handle.getRoot();
-	    return root.getName() + ", line " + root.getLine();
+	    return name + ", line " + root.getLine();
     }
 
 	public String toString() {

Modified: trunk/src/org/griphyn/vdl/mapping/DuplicateMappingChecker.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/DuplicateMappingChecker.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/DuplicateMappingChecker.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -15,6 +15,7 @@
 import java.util.Map;
 
 import org.apache.log4j.Logger;
+import org.griphyn.vdl.mapping.nodes.AbstractDataNode;
 import org.griphyn.vdl.util.VDL2Config;
 import org.griphyn.vdl.util.VDL2ConfigProperties;
 

Deleted: trunk/src/org/griphyn/vdl/mapping/ExternalDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/ExternalDataNode.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/ExternalDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -1,163 +0,0 @@
-/*
- * Copyright 2012 University of Chicago
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package org.griphyn.vdl.mapping;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import k.thr.LWThread;
-
-import org.apache.log4j.Logger;
-import org.griphyn.vdl.karajan.Loader;
-import org.griphyn.vdl.type.Types;
-import org.griphyn.vdl.type.impl.FieldImpl;
-
-public class ExternalDataNode extends AbstractDataNode implements RootHandle {
-
-	static final String DATASET_URI_PREFIX = "dataset:external:";
-
-	public static final Logger logger = Logger.getLogger(ExternalDataNode.class);
-	
-	private static long datasetIDCounter = 850000000000l;
-
-	private static final String datasetIDPartialID = Loader.getUUID();
-	
-    // previously in mapper params
-    private int line = -1;
-    private LWThread thread;
-    private boolean input;
-
-	
-	public ExternalDataNode(String name) {
-	    super(new FieldImpl(name, Types.EXTERNAL));
-	}
-
-    public int getLine() {
-        return line;
-    }
-
-    public void setLine(int line) {
-        this.line = line;
-    }
-
-    public boolean isInput() {
-        return input;
-    }
-
-    public void setInput(boolean input) {
-        this.input = input;
-    }
-
-    public void setThread(LWThread thread) {
-        this.thread = thread;
-    }
-
-    public LWThread getThread() {
-        return thread;
-    }
-
-	public String getName() {
-        return (String) getField().getId();
-    }
-	
-	@Override
-    public void setName(String name) {
-        getField().setId(name);
-    }
-
-	@Override
-    public void init(Mapper mapper) {
-    }
-
-    public boolean isRestartable() {
-		return true;
-	}
-
-	public RootHandle getRoot() {
-		return this;
-	}
-
-	public DSHandle getField(Path path) throws InvalidPathException {
-		if (path.isEmpty()) {
-			return this;
-		} 
-		else {
-			throw new InvalidPathException(path, this);
-		}
-	}
-	
-	protected void getFields(List<DSHandle> fields, Path path) throws InvalidPathException {
-	    // nothing
-	}
-
-	public void set(DSHandle handle) {
-		throw new UnsupportedOperationException(this.getDisplayableName() + " is an external dataset and cannot be set");
-	}
-
-	public Map<Comparable<?>, DSHandle> getArrayValue() {
-	    throw new UnsupportedOperationException("cannot get value of external dataset");
-	}
-
-	public boolean isArray() {
-		return false;
-	}
-
-	public Collection<Path> getFringePaths() throws HandleOpenException {
-	    return Collections.singletonList(Path.EMPTY_PATH);
-	}
-
-	public Path getPathFromRoot() {
-		return Path.EMPTY_PATH;
-	}
-
-	public Mapper getMapper() {
-		return null;
-	}
-
-	protected String makeIdentifierURIString() {
-		datasetIDCounter++;
-		return DATASET_URI_PREFIX + datasetIDPartialID + ":" + datasetIDCounter; 
-	}
-
-	public DSHandle createDSHandle(String fieldName) {
-	    throw new UnsupportedOperationException("cannot create new field in external dataset");
-	}
-
-	public DSHandle getParent() {
-	    return null;
-	}
-
-    @Override
-    protected AbstractDataNode getParentNode() {
-        return null;
-    }
-
-    @Override
-    public synchronized void closeDeep() {
-        if (!this.isClosed()) {
-            /*
-             * Need to override this and set a value since 
-             * this is skipped by the normal stageout mechanism which
-             * does that
-             */
-            this.setValue(FILE_VALUE);
-        }
-    }
-}

Modified: trunk/src/org/griphyn/vdl/mapping/InvalidPathException.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/InvalidPathException.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/InvalidPathException.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -20,7 +20,9 @@
  */
 package org.griphyn.vdl.mapping;
 
+import org.griphyn.vdl.mapping.nodes.AbstractDataNode;
 
+
 public class InvalidPathException extends Exception {
 	public InvalidPathException(String path, DSHandle source) {
 		super(getMessage(path, source));

Modified: trunk/src/org/griphyn/vdl/mapping/Mapper.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/Mapper.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/Mapper.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -21,6 +21,7 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.griphyn.vdl.mapping.nodes.AbstractDataNode;
 import org.griphyn.vdl.type.Type;
 
 /** This interface must be implemented by a Java class that represents

Modified: trunk/src/org/griphyn/vdl/mapping/MappingParamSet.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/MappingParamSet.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/MappingParamSet.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -7,6 +7,7 @@
 import java.util.Map;
 
 import org.griphyn.vdl.karajan.lib.Tracer;
+import org.griphyn.vdl.mapping.nodes.AbstractDataNode;
 
 
 public abstract class MappingParamSet {

Modified: trunk/src/org/griphyn/vdl/mapping/MissingDataException.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/MissingDataException.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/MissingDataException.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -9,6 +9,8 @@
  */
 package org.griphyn.vdl.mapping;
 
+import org.griphyn.vdl.mapping.nodes.AbstractDataNode;
+
 public class MissingDataException extends RuntimeException {
     public MissingDataException(AbstractDataNode n, PhysicalFormat pf) {
         super("File not found for variable '" + n.getFullName() + "': " + pf);

Modified: trunk/src/org/griphyn/vdl/mapping/NotCompositeException.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/NotCompositeException.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/NotCompositeException.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -9,6 +9,8 @@
  */
 package org.griphyn.vdl.mapping;
 
+import org.griphyn.vdl.mapping.nodes.AbstractDataNode;
+
 public class NotCompositeException extends RuntimeException {
     private AbstractDataNode node;
 

Modified: trunk/src/org/griphyn/vdl/mapping/NullMapper.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/NullMapper.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/NullMapper.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -14,6 +14,7 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.griphyn.vdl.mapping.nodes.AbstractDataNode;
 import org.griphyn.vdl.type.Type;
 
 

Modified: trunk/src/org/griphyn/vdl/mapping/OpenArrayEntries.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/OpenArrayEntries.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/OpenArrayEntries.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -17,13 +17,14 @@
 import k.rt.ConditionalYield;
 
 import org.griphyn.vdl.karajan.Pair;
+import org.griphyn.vdl.mapping.nodes.ArrayHandle;
 
 public class OpenArrayEntries implements Iterable<List<?>> {
     private List<Comparable<?>> keyList;
     private Map<Comparable<?>, DSHandle> array;
-    private ArrayDataNode source;
+    private ArrayHandle source;
 
-    public OpenArrayEntries(List<Comparable<?>> keyList, Map<Comparable<?>, DSHandle> array, ArrayDataNode source) {
+    public OpenArrayEntries(List<Comparable<?>> keyList, Map<Comparable<?>, DSHandle> array, ArrayHandle source) {
         this.keyList = keyList;
         this.array = array;
         this.source = source;

Modified: trunk/src/org/griphyn/vdl/mapping/Path.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/Path.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/Path.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -178,6 +178,10 @@
 	public Comparable<?> getKey(int index) {
         return entries.get(index).key;
     }
+	
+	public Entry getEntry(int index) {
+	    return entries.get(index);
+	}
 
 	public int size() {
 		return entries == null ? 0 : entries.size();
@@ -198,6 +202,10 @@
 	public Path butFirst() {
 		return subPath(1);
 	}
+	
+	public Path butLast() {
+	    return subPath(0, entries.size() - 1);
+	}
 
 	public Path subPath(int fromIndex) {
 		return subPath(fromIndex, entries.size());

Deleted: trunk/src/org/griphyn/vdl/mapping/RootArrayDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/RootArrayDataNode.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/RootArrayDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -1,189 +0,0 @@
-/*
- * Copyright 2012 University of Chicago
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package org.griphyn.vdl.mapping;
-
-import k.rt.Future;
-import k.rt.FutureListener;
-import k.thr.LWThread;
-
-import org.apache.log4j.Logger;
-import org.globus.cog.karajan.futures.FutureNotYetAvailable;
-import org.griphyn.vdl.karajan.lib.Tracer;
-import org.griphyn.vdl.type.Field;
-import org.griphyn.vdl.type.Type;
-
-public class RootArrayDataNode extends ArrayDataNode implements FutureListener, RootHandle {
-
-    Logger logger = Logger.getLogger(RootArrayDataNode.class);
-    
-	private boolean initialized = false;
-	private Mapper mapper;
-	private AbstractDataNode waitingMapperParam;
-	private DuplicateMappingChecker dmc;
-	
-    // previously in mapper params
-    private int line = -1;
-    private LWThread thread;
-    private boolean input;
-
-	
-	public RootArrayDataNode(Type type) {
-	    this("?", type);
-	}
-	/**
-	 * Instantiate a root array data node with specified type.
-	 */
-	public RootArrayDataNode(String name, Type type) {
-		super(Field.Factory.getImmutableField(name, type), null, null);
-	}
-	
-	public RootArrayDataNode(String name, Type type, DuplicateMappingChecker dmc) {
-	    this(name, type);
-	    this.dmc = dmc;
-	}
-	
-    public int getLine() {
-        return line;
-    }
-
-    public void setLine(int line) {
-        this.line = line;
-    }
-
-    public boolean isInput() {
-        return input;
-    }
-
-    public void setInput(boolean input) {
-        this.input = input;
-    }
-
-    public void setThread(LWThread thread) {
-        this.thread = thread;
-    }
-
-    public LWThread getThread() {
-        return thread;
-    }
-	
-	public String getName() {
-        return (String) getField().getId();
-    }
-	
-	@Override
-    public void setName(String name) {
-        getField().setId(name);
-    }
-
-	@Override
-	public void init(Mapper mapper) {
-		this.mapper = mapper;
-		if (this.mapper == null) {
-			initialized();
-			if (isInput()) {
-                // Empty array. Clearly only in test cases.
-                closeDeep();
-            }
-		}
-		else {
-			innerInit();
-		}
-	}
-
-	private synchronized void innerInit() {
-		if (logger.isDebugEnabled()) {
-		    logger.debug("innerInit: " + this);
-		}
-	    
-		waitingMapperParam = mapper.getFirstOpenParameter();
-        if (waitingMapperParam != null) {
-            waitingMapperParam.addListener(this, false);
-            if (variableTracer.isEnabled()) {
-                variableTracer.trace(getThread(), getLine(), getName() + " WAIT " 
-                    + Tracer.getVarName(waitingMapperParam));
-            }
-            return;
-        }
-	    
-        mapper.initialize(this);
-		initialized();
-		checkInputs();
-		if (isClosed()) {
-		    notifyListeners();
-		}
-	}
-
-	private void checkInputs() {
-		try {
-			RootDataNode.checkInputs(this, dmc);
-		}
-		catch (DependentException e) {
-			setValue(new MappingDependentException(this, e));
-		}
-	}
-	
-	public void futureUpdated(Future f) {
-	    try {
-            innerInit();
-        }
-        catch (Exception e) {
-            this.setValue(new MappingException(this, e));
-        }
-    }
-	
-	public RootHandle getRoot() {
-		return this;
-	}
-
-	public DSHandle getParent() {
-		return null;
-	}
-
-	public synchronized Mapper getMapper() {
-		if (initialized) {
-			return mapper;
-		}
-        if (waitingMapperParam == null) {
-            return null;
-        }
-        else {
-            throw new FutureNotYetAvailable(waitingMapperParam);
-        }
-	}
-	
-	public Mapper getActualMapper() {
-        return mapper;
-    }
-
-	public boolean isArray() {
-		return true;
-	}
-
-    public void setValue(Object value) {
-        super.setValue(value);
-        initialized();
-    }
-
-    private synchronized void initialized() {
-        initialized = true;
-        waitingMapperParam = null;
-        if (variableTracer.isEnabled()) {
-            variableTracer.trace(getThread(), getLine(), getName() + " INITIALIZED " + mapper);
-        }
-    }
-}

Deleted: trunk/src/org/griphyn/vdl/mapping/RootDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/RootDataNode.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/RootDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -1,319 +0,0 @@
-/*
- * Copyright 2012 University of Chicago
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/*
- * Created on Jun 15, 2006
- */
-package org.griphyn.vdl.mapping;
-
-import java.util.Collection;
-
-import k.rt.Future;
-import k.rt.FutureListener;
-import k.thr.LWThread;
-
-import org.apache.log4j.Logger;
-import org.globus.cog.karajan.futures.FutureNotYetAvailable;
-import org.griphyn.vdl.karajan.lib.Tracer;
-import org.griphyn.vdl.type.Field;
-import org.griphyn.vdl.type.Type;
-
-public class RootDataNode extends AbstractDataNode implements FutureListener, RootHandle {
-
-    static Logger logger = Logger.getLogger(RootDataNode.class);
-    
-	private boolean initialized = false;
-	private Mapper mapper;
-	private AbstractDataNode waitingMapperParam;
-	private DuplicateMappingChecker dmc;
-	
-    // previously in mapper params
-    private int line = -1;
-    private LWThread thread;
-    private boolean input;
-
-	
-	public RootDataNode(String name, Type type, DuplicateMappingChecker dmc) {
-		super(Field.Factory.getImmutableField(name, type));
-		this.dmc = dmc;
-	}
-	
-	public RootDataNode(Type type, Object value) {
-        this("?", type, value);
-    }
-	
-	public RootDataNode(String name, Type type) {
-	    this(name, type, null);
-	}
-	
-	public RootDataNode(String name, Type type, Object value) {
-	    this(name, type);
-	    initialized();
-	    setValue(value);
-	}
-	
-	    public int getLine() {
-        return line;
-    }
-
-    public void setLine(int line) {
-        this.line = line;
-    }
-
-    public boolean isInput() {
-        return input;
-    }
-
-    public void setInput(boolean input) {
-        this.input = input;
-    }
-
-    public void setThread(LWThread thread) {
-        this.thread = thread;
-    }
-
-    public LWThread getThread() {
-        return thread;
-    }
-	
-	public String getName() {
-	    return (String) getField().getId();
-	}
-
-	@Override
-    public void setName(String name) {
-	    getField().setId(name);
-    }
-	
-    public void init(Mapper mapper) {
-		this.mapper = mapper;
-		if (mapper == null) { 
-			initialized();
-		} 
-		else {
-			innerInit();
-		}
-	}
-
-	/** must have this.params set to the appropriate parameters before
-	    being called. 
-	 * @throws HandleOpenException */
-	private synchronized void innerInit() {
-	    waitingMapperParam = mapper.getFirstOpenParameter();
-	    if (waitingMapperParam != null) {
-            waitingMapperParam.addListener(this);
-            if (variableTracer.isEnabled()) {
-                variableTracer.trace(getThread(), getLine(), getDisplayableName() + " WAIT " 
-                    + Tracer.getVarName(waitingMapperParam));
-            }
-            return;
-	    }
-	    
-		// initialized means that this data has its mapper initialized
-		// this should be called before checkInputs because the latter
-		// may trigger calls to things that try to access this data node's
-		// mapper
-	    mapper.initialize(this);
-        initialized();
-		checkInputs();
-		
-		if (isClosed()) {
-		    notifyListeners();
-		}
-	}
-
-	private void checkInputs() {
-		try {
-			checkInputs(this, dmc);
-		}
-		catch (DependentException e) {
-			setValue(new MappingDependentException(this, e));
-		}
-	}
-
-	public void futureUpdated(Future f) {
-		try {
-            innerInit();
-        }
-        catch (Exception e) {
-            this.setValue(new MappingException(this, e));
-        }
-	}
-
-
-	static protected void checkInputs(RootHandle root, DuplicateMappingChecker dmc) {
-	    Mapper mapper = root.getActualMapper();
-		if (root.isInput()) {
-			addExisting(mapper.existing(), mapper, root, root);
-			checkConsistency(root, root, dmc);
-		}
-		else if (mapper.isStatic()) {
-		    if (root.isClosed()) {
-		        // this means that code that would have used this variable is already done
-		        // which can happen in cases such as if(false) {a = ...}
-		        return;
-		    }
-		    if (!root.getType().isComposite()) {
-		        return;
-		    }
-			// Static mappers are (array) mappers which know the size of
-			// an array statically. A good example is the fixed array mapper
-		    if (logger.isDebugEnabled()) {
-		        logger.debug("mapper: " + mapper);
-		    }
-			for (Path p : mapper.existing()) {
-				try {
-					// Try to get the path in order to check that the 
-				    // path is valid - we'll get an exception if not
-					DSHandle h = root.getField(p);
-					if (variableTracer.isEnabled()) {
-					    variableTracer.trace(root.getThread(), root.getLine(), 
-					        root.getName() + " MAPPING " + p + ", " + mapper.map(p));
-					}
-				}
-				catch (InvalidPathException e) {
-					throw new IllegalStateException
-					("mapper.existing() returned a path " + 
-					" that it cannot subsequently map: " + 
-					" root: " + root + " path: " + p);
-				}
-			}
-			if (root.isArray()) {
-			    root.closeArraySizes();
-			}
-			checkConsistency(root, root, dmc);
-		}
-	}
-
-	public static void addExisting(Collection<Path> existing, Mapper mapper, RootHandle root, DSHandle var) {
-	    boolean any = false;
-		for (Path p : existing) {
-            try {
-                DSHandle field = var.getField(p);
-                field.setValue(FILE_VALUE);
-                if (variableTracer.isEnabled()) {
-                    variableTracer.trace(root.getThread(), root.getLine(), 
-                        root.getName() + " MAPPING " + p + ", " + mapper.map(p));
-                }
-                any = true;
-            }
-            catch (InvalidPathException e) {
-                throw new IllegalStateException("Structure of mapped data is " +
-                        "incompatible with the mapped variable type: " + e.getMessage());
-            }
-            catch (NotCompositeException e) {
-                throw new IllegalStateException("Cannot map multiple files to variable '" + 
-                    e.getDataNode().getFullName() + "' of non composite type '" + 
-                    e.getDataNode().getType() + "'");
-            }
-        }
-        var.closeDeep();
-        if (!any && variableTracer.isEnabled()) {
-            variableTracer.trace(root.getThread(), root.getLine(), 
-                root.getName() + " MAPPING no files found");
-        }
-    }
-
-    public static void checkConsistency(RootHandle root, DSHandle handle, DuplicateMappingChecker dmc) {
-		if (handle.getType().isArray()) {
-			// any number of indices is ok
-			try {
-			    for (DSHandle dh : handle.getFields(Path.CHILDREN)) {
-					checkConsistency(root, dh, dmc);
-				}
-			}
-			catch (HandleOpenException e) {
-				// TODO init() should throw some checked exception
-				throw new RuntimeException("Mapper consistency check failed for " + handle
-						+ ". A HandleOpenException was thrown during consistency checking for "+e.getSource(), e);
-			}
-			catch (InvalidPathException e) {
-				e.printStackTrace();
-			}
-		}
-		else {
-			// all fields must be present
-			Type type = handle.getType();
-			if (!type.isPrimitive() && !type.isComposite()) {
-			    // mapped. Feed the DMC.
-			    PhysicalFormat f = root.getActualMapper().map(handle.getPathFromRoot());
-			    if (root.isInput()) {
-			        dmc.addRead(f, handle);
-			    }
-			    else {
-			        dmc.addWrite(f, handle);
-			    }
-			}
-			for (String fieldName : type.getFieldNames()) {
-				Path fieldPath = Path.parse(fieldName);
-				try {
-					checkConsistency(root, handle.getField(fieldPath), dmc);
-				}
-				catch (InvalidPathException e) {
-					throw new RuntimeException("Data set initialization failed for " + handle
-							+ ". Missing required field: " + fieldName);
-				}
-			}
-		}
-	}
-	
-	public RootHandle getRoot() {
-		return this;
-	}
-
-	public DSHandle getParent() {
-		return null;
-	}
-
-	@Override
-    protected AbstractDataNode getParentNode() {
-        return null;
-    }
-
-    public synchronized Mapper getMapper() {
-		if (initialized) {
-			return mapper;
-		}
-		if (waitingMapperParam == null) {
-		    return null;
-		}
-		else {
-		    throw new FutureNotYetAvailable(waitingMapperParam);
-		}
-	}
-	
-	public Mapper getActualMapper() {
-        return mapper;
-    }
-
-	public boolean isArray() {
-		return false;
-	}
-
-	public void setValue(Object value) {
-		super.setValue(value);
-		initialized();
-	}
-
-	private synchronized void initialized() {
-		initialized = true;
-		waitingMapperParam = null;
-		if (variableTracer.isEnabled()) {
-            variableTracer.trace(getThread(), getLine(), getName() + " INITIALIZED " + mapper);
-        }
-	}
-}

Modified: trunk/src/org/griphyn/vdl/mapping/RootHandle.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/RootHandle.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/RootHandle.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -26,4 +26,6 @@
     Mapper getActualMapper();
     boolean isArray();
     void closeArraySizes();
+    
+    void mapperInitialized(Mapper mapper);
 }

Modified: trunk/src/org/griphyn/vdl/mapping/file/AbstractFileMapperParams.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/file/AbstractFileMapperParams.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/file/AbstractFileMapperParams.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -3,7 +3,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
-import org.griphyn.vdl.mapping.AbstractDataNode;
+import org.griphyn.vdl.mapping.nodes.AbstractDataNode;
 import org.griphyn.vdl.mapping.MappingParamSet;
 
 

Modified: trunk/src/org/griphyn/vdl/mapping/file/ArrayFileMapperParams.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/file/ArrayFileMapperParams.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/file/ArrayFileMapperParams.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -3,7 +3,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
-import org.griphyn.vdl.mapping.AbstractDataNode;
+import org.griphyn.vdl.mapping.nodes.AbstractDataNode;
 import org.griphyn.vdl.mapping.MappingParamSet;
 import org.griphyn.vdl.mapping.DSHandle;
 

Modified: trunk/src/org/griphyn/vdl/mapping/file/CSVMapperParams.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/file/CSVMapperParams.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/file/CSVMapperParams.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -3,7 +3,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
-import org.griphyn.vdl.mapping.AbstractDataNode;
+import org.griphyn.vdl.mapping.nodes.AbstractDataNode;
 import org.griphyn.vdl.mapping.MappingParamSet;
 import org.griphyn.vdl.mapping.DSHandle;
 

Modified: trunk/src/org/griphyn/vdl/mapping/file/ExternalMapperParams.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/file/ExternalMapperParams.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/file/ExternalMapperParams.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -6,8 +6,8 @@
 import java.util.List;
 import java.util.Map;
 
-import org.griphyn.vdl.mapping.AbstractDataNode;
 import org.griphyn.vdl.mapping.MappingParamSet;
+import org.griphyn.vdl.mapping.nodes.AbstractDataNode;
 
 
 public class ExternalMapperParams extends MappingParamSet {

Modified: trunk/src/org/griphyn/vdl/mapping/file/FixedArrayFileMapperParams.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/file/FixedArrayFileMapperParams.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/file/FixedArrayFileMapperParams.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -3,7 +3,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
-import org.griphyn.vdl.mapping.AbstractDataNode;
+import org.griphyn.vdl.mapping.nodes.AbstractDataNode;
 import org.griphyn.vdl.mapping.MappingParamSet;
 import org.griphyn.vdl.mapping.DSHandle;
 

Modified: trunk/src/org/griphyn/vdl/mapping/file/MappingParamFileGenerator.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/file/MappingParamFileGenerator.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/file/MappingParamFileGenerator.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -132,7 +132,7 @@
     }
 
     private static final List<String> IMPORTS = Arrays.asList("java.util.Arrays", "java.util.Collection", 
-        "java.util.List", "org.griphyn.vdl.mapping.AbstractDataNode", "org.griphyn.vdl.mapping.MappingParamSet");
+        "java.util.List", "org.griphyn.vdl.mapping.nodes.AbstractDataNode", "org.griphyn.vdl.mapping.MappingParamSet");
 
     private static void writeFile(File nf, String pkg, List<Param> params, Map<String, Object> opts) throws IOException {
         String name = nf.getName().substring(0, nf.getName().lastIndexOf('.'));

Modified: trunk/src/org/griphyn/vdl/mapping/file/RegularExpressionMapperParams.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/file/RegularExpressionMapperParams.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/file/RegularExpressionMapperParams.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -3,7 +3,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
-import org.griphyn.vdl.mapping.AbstractDataNode;
+import org.griphyn.vdl.mapping.nodes.AbstractDataNode;
 import org.griphyn.vdl.mapping.MappingParamSet;
 import org.griphyn.vdl.mapping.DSHandle;
 

Modified: trunk/src/org/griphyn/vdl/mapping/file/SimpleFileMapperParams.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/file/SimpleFileMapperParams.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/file/SimpleFileMapperParams.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -3,7 +3,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
-import org.griphyn.vdl.mapping.AbstractDataNode;
+import org.griphyn.vdl.mapping.nodes.AbstractDataNode;
 import org.griphyn.vdl.mapping.MappingParamSet;
 
 

Modified: trunk/src/org/griphyn/vdl/mapping/file/SingleFileMapperParams.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/file/SingleFileMapperParams.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/file/SingleFileMapperParams.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -5,8 +5,8 @@
 import java.util.List;
 
 import org.griphyn.vdl.mapping.AbsFile;
-import org.griphyn.vdl.mapping.AbstractDataNode;
 import org.griphyn.vdl.mapping.MappingParamSet;
+import org.griphyn.vdl.mapping.nodes.AbstractDataNode;
 
 
 public class SingleFileMapperParams extends MappingParamSet {

Modified: trunk/src/org/griphyn/vdl/mapping/file/StructuredRegularExpressionMapper.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/file/StructuredRegularExpressionMapper.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/file/StructuredRegularExpressionMapper.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -69,7 +69,7 @@
 		Collection<Path> output = new ArrayList<Path>();
 		Collection<DSHandle> sourceFields;
 		try {
-			sourceFields = sourceHandle.getFields(Path.CHILDREN);
+			sourceFields = sourceHandle.getAllFields();
 		}
 		catch (InvalidPathException ipe) {
 			return Collections.emptyList();

Modified: trunk/src/org/griphyn/vdl/mapping/file/StructuredRegularExpressionMapperParams.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/file/StructuredRegularExpressionMapperParams.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/file/StructuredRegularExpressionMapperParams.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -3,7 +3,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
-import org.griphyn.vdl.mapping.AbstractDataNode;
+import org.griphyn.vdl.mapping.nodes.AbstractDataNode;
 import org.griphyn.vdl.mapping.MappingParamSet;
 import org.griphyn.vdl.mapping.DSHandle;
 

Modified: trunk/src/org/griphyn/vdl/mapping/file/TestMapperParams.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/file/TestMapperParams.java	2014-05-08 21:57:35 UTC (rev 7838)
+++ trunk/src/org/griphyn/vdl/mapping/file/TestMapperParams.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -3,7 +3,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
-import org.griphyn.vdl.mapping.AbstractDataNode;
+import org.griphyn.vdl.mapping.nodes.AbstractDataNode;
 import org.griphyn.vdl.mapping.MappingParamSet;
 
 

Added: trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedArrayDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedArrayDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedArrayDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,158 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.griphyn.vdl.mapping.ClosedArrayEntries;
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.HandleOpenException;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.type.Field;
+import org.griphyn.vdl.type.Types;
+
+
+public abstract class AbstractClosedArrayDataNode extends AbstractClosedDataNode implements ArrayHandle {
+    private DSHandle[] values;
+
+    public AbstractClosedArrayDataNode(Field field, List<?> values) {
+    	super(field);
+    	setValues(values);
+    }
+    
+    private void setValues(List<?> values) {
+        int sz = values.size();
+        this.values = new DSHandle[sz];
+    	int index = 0;
+        Iterator<?> i = values.iterator();
+        while (i.hasNext()) {
+            Object n = i.next();
+            if (n instanceof DSHandle) {
+                this.values[index] = (DSHandle) n;
+            }
+            else if (n instanceof String) {
+            	this.values[index] = NodeFactory.newNode(Field.Factory.createField(index, Types.STRING), getRoot(), this, n);
+            }
+            else {
+                throw new RuntimeException(
+                        "An array variable can only be initialized by a list of DSHandle values");
+            }
+            index++;
+        }
+    }
+    
+    @Override
+    protected Object getRawValue() {
+        return null;
+    }
+    
+    @Override
+    public synchronized DSHandle getField(Comparable<?> key) throws NoSuchFieldException {
+        int index = ((Integer) key).intValue();
+        if (index < 0 || index >= values.length) {
+            throw new NoSuchFieldException(String.valueOf(index));
+        }
+        return values[index];
+    }
+
+    @Override
+    public Object getValue() {
+        return getArrayValue();
+    }
+    
+    @Override
+    public Map<Comparable<?>, DSHandle> getArrayValue() {
+        return new AbstractMap<Comparable<?>, DSHandle>() {
+            @Override
+            public Set<Map.Entry<Comparable<?>, DSHandle>> entrySet() {
+                return new AbstractSet<Map.Entry<Comparable<?>, DSHandle>>() {
+                    @Override
+                    public Iterator<Map.Entry<Comparable<?>, DSHandle>> iterator() {
+                        return new Iterator<Map.Entry<Comparable<?>, DSHandle>>() {
+                            private int index = 0;
+                            
+                            @Override
+                            public boolean hasNext() {
+                                return index < values.length;
+                            }
+
+                            @Override
+                            public Map.Entry<Comparable<?>, DSHandle> next() {
+                                final int i = index;
+                                index++;
+                                return new Map.Entry<Comparable<?>, DSHandle>() {
+                                    @Override
+                                    public Comparable<?> getKey() {
+                                        return Integer.valueOf(i);
+                                    }
+
+                                    @Override
+                                    public DSHandle getValue() {
+                                        return values[i];
+                                    }
+
+                                    @Override
+                                    public DSHandle setValue(DSHandle value) {
+                                        throw new UnsupportedOperationException();
+                                    }
+                                };
+                            }
+
+                            @Override
+                            public void remove() {
+                                throw new UnsupportedOperationException();
+                            }
+                        };
+                    }
+
+                    @Override
+                    public int size() {
+                        return values.length;
+                    }
+                };
+            }
+        };
+    }
+    
+    @Override
+    public Iterable<List<?>> entryList() {
+        return new ClosedArrayEntries(getArrayValue());
+    }
+    
+    @Override
+    public void getFringePaths(List<Path> list, Path myPath) throws HandleOpenException {
+        for (int i = 0; i < values.length; i++) {
+            Path fullPath = myPath.addLast(i, true);
+            ((AbstractDataNode) values[i]).getFringePaths(list, fullPath);
+        }
+    }
+    
+    @Override
+    protected void getLeaves(List<DSHandle> list) throws HandleOpenException {
+        for (DSHandle h : values) {
+            AbstractDataNode child = (AbstractDataNode) h;
+            child.getLeaves(list);
+        }
+    }
+    
+    public boolean isArray() {
+        return true;
+    }
+
+    @Override
+    public int arraySize() {
+        return values.length;
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,72 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import k.rt.FutureListener;
+
+import org.globus.cog.karajan.compiled.nodes.Node;
+import org.griphyn.vdl.mapping.OOBYield;
+import org.griphyn.vdl.type.Field;
+
+public abstract class AbstractClosedDataNode extends AbstractDataNode {
+
+    public AbstractClosedDataNode(Field field) {
+        super(field);
+    }
+
+    @Override
+    public boolean isClosed() {
+        return true;
+    }
+    
+    @Override
+    public void closeShallow() {
+        // already closed
+    }
+
+    @Override
+    public void closeDeep() {
+        // already closed
+    }
+    
+    public void setValue(Object value) {
+        throw new IllegalArgumentException(this.getFullName() 
+            + " is closed with a value of " + this.getValue());
+    }
+
+    @Override
+    protected boolean addListener0(FutureListener l) {
+        throw new UnsupportedOperationException("Cannot add listener to closed node");
+    }
+
+    @Override
+    protected void notifyListeners() {
+    }
+
+    @Override
+    public void setWriteRefCount(int count) {
+        if (count != 0) {
+            throw new UnsupportedOperationException("Attempt to set non-zero write ref count on read-only node");
+        }
+    }
+
+    @Override
+    public int updateWriteRefCount(int delta) {
+        throw new UnsupportedOperationException("Attempt to update write ref count on read-only node");
+    }
+    
+    @Override
+    public synchronized void waitFor(Node who) {
+    }
+    
+    @Override
+    public synchronized void waitFor() throws OOBYield {
+    }    
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedMappedSingleDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedMappedSingleDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedMappedSingleDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,33 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import java.util.List;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.HandleOpenException;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.type.Field;
+
+public abstract class AbstractClosedMappedSingleDataNode extends AbstractClosedNonCompositeDataNode {
+    
+    public AbstractClosedMappedSingleDataNode(Field field, Object value) {
+        super(field, value);
+    }
+    
+    public void getFringePaths(List<Path> list, Path myPath) throws HandleOpenException {
+        list.add(myPath);
+    }
+    
+    @Override
+    protected void getLeaves(List<DSHandle> list) throws HandleOpenException {
+        list.add(this);
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedNonCompositeDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedNonCompositeDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedNonCompositeDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,42 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import org.griphyn.vdl.mapping.DataDependentException;
+import org.griphyn.vdl.mapping.DependentException;
+import org.griphyn.vdl.type.Field;
+
+public abstract class AbstractClosedNonCompositeDataNode extends AbstractClosedDataNode {
+    private Object value;
+    
+    public AbstractClosedNonCompositeDataNode(Field field, Object value) {
+        super(field);
+        this.value = value;
+    }
+    
+    public AbstractClosedNonCompositeDataNode(Field field, DependentException e) {
+        super(field);
+        this.value = new DataDependentException(this, e);
+    }
+
+    @Override
+    public synchronized Object getValue() {
+        return value;
+    }
+    
+    @Override
+    protected Object getRawValue() {
+        return value;
+    }
+        
+    public boolean isArray() {
+        return false;
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedPrimitiveDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedPrimitiveDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedPrimitiveDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,38 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import java.util.List;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.DependentException;
+import org.griphyn.vdl.mapping.HandleOpenException;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.type.Field;
+
+public abstract class AbstractClosedPrimitiveDataNode extends AbstractClosedNonCompositeDataNode {
+    
+    public AbstractClosedPrimitiveDataNode(Field field, Object value) {
+        super(field, value);
+    }
+    
+    public AbstractClosedPrimitiveDataNode(Field field, DependentException e) {
+        super(field, e);
+    }
+    
+    public void getFringePaths(List<Path> list, Path parentPath) throws HandleOpenException {
+        // only mappable paths
+    }
+    
+    @Override
+    protected void getLeaves(List<DSHandle> list) throws HandleOpenException {
+        // only mappable paths
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedStructDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedStructDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/AbstractClosedStructDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,80 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.HandleOpenException;
+import org.griphyn.vdl.mapping.InvalidPathException;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.type.Field;
+import org.griphyn.vdl.type.Type;
+
+public abstract class AbstractClosedStructDataNode extends AbstractClosedDataNode {
+    private DSHandle[] fields;
+    
+    public AbstractClosedStructDataNode(Field field) {
+        super(field);
+        fields = new DSHandle[field.getType().getFields().size()];
+    }
+    
+    protected void setField(String name, DSHandle n) throws NoSuchFieldException {
+        fields[field.getType().getFieldIndex(name)] = n;
+    }
+    
+    @Override
+    public synchronized DSHandle getField(Comparable<?> key) throws NoSuchFieldException {
+        return fields[field.getType().getFieldIndex((String) key)];
+    }
+    
+    @Override
+    public Collection<DSHandle> getAllFields() throws InvalidPathException, HandleOpenException {
+        return Arrays.asList(fields);
+    }
+
+    @Override
+    public void getFringePaths(List<Path> list, Path myPath) throws HandleOpenException {
+        Type t = field.getType();
+        for (Field f : t.getFields()) {
+            AbstractDataNode child;
+            try {
+                child = (AbstractDataNode) getField(f.getId());
+            }
+            catch (Exception e) {
+                throw new RuntimeException("Structure inconsistency detected for field " + f);
+            }
+            Path fullPath = myPath.addLast(f.getId());
+            child.getFringePaths(list, fullPath);
+        }
+    }
+    
+    @Override
+    protected void getLeaves(List<DSHandle> list) throws HandleOpenException {
+        Type t = field.getType();
+        for (Field f : t.getFields()) {
+            AbstractDataNode child;
+            try {
+                child = (AbstractDataNode) getField(f.getId());
+            }
+            catch (Exception e) {
+                throw new RuntimeException("Structure inconsistency detected for field " + f);
+            }
+            child.getLeaves(list);
+        }
+    }
+
+    
+    public boolean isArray() {
+        return false;
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/AbstractDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/AbstractDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/AbstractDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,485 @@
+/*
+ * Copyright 2012 University of Chicago
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*
+ * Created on Jun 6, 2006
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import k.rt.FutureListener;
+import k.rt.FutureValue;
+
+import org.apache.log4j.Logger;
+import org.globus.cog.karajan.compiled.nodes.Node;
+import org.griphyn.vdl.karajan.Loader;
+import org.griphyn.vdl.karajan.WaitingThreadsMonitor;
+import org.griphyn.vdl.karajan.lib.Tracer;
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.DSHandleListener;
+import org.griphyn.vdl.mapping.HandleOpenException;
+import org.griphyn.vdl.mapping.InvalidPathException;
+import org.griphyn.vdl.mapping.Mapper;
+import org.griphyn.vdl.mapping.OOBYield;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.PhysicalFormat;
+import org.griphyn.vdl.type.Field;
+import org.griphyn.vdl.type.Type;
+import org.griphyn.vdl.util.VDL2Config;
+
+
+
+public abstract class AbstractDataNode implements DSHandle, FutureValue {
+    public static final Object FILE_VALUE = new Object() {
+        public String toString() {
+            return "<FILE>";
+        }
+    };
+
+    static final String DATASET_URI_PREFIX = "dataset:";
+
+    public static final Logger logger = Logger.getLogger(AbstractDataNode.class);
+
+    /**
+     * Datasets are identified within a run by this sequence number and the
+     * partial ID field. The initial value is chosen to aid human recognition of
+     * sequence numbers in the wild. There is no requirement that it start at
+     * this (or any other) particular value. Note that this introduces a maximum
+     * on the number of datasets which can be dealt with in any run to be about
+     * 2^62.
+     */
+    private static long datasetIDCounter = 720000000000l;
+
+    /**
+     * This is used to provide a (hopefully) globally unique identifier for each
+     * time the datasetIDCounter is reset (whenever this class is loaded, which
+     * will usually happen once per JVM). No meaning should be inferred from
+     * this value - it exists purely for making unique URIs.
+     */
+    private static final String datasetIDPartialID = Loader.getUUID();
+    
+    public static boolean provenance = false;
+    static {
+        try {
+        	provenance = VDL2Config.getConfig().getProvenanceLog();
+        }
+        catch (IOException e) {
+        }
+    }
+    
+    protected Field field;
+    private String identifier;
+        
+    protected static final Tracer variableTracer = Tracer.getTracer("VARIABLE");
+
+    protected AbstractDataNode(Field field) {
+        this.field = field;
+    }
+    
+    public void initialize() {        
+    }
+    
+    public String getName() {
+        return getRoot().getName();
+    }
+    
+    @Override
+    public void setName(String name) {
+        throw new UnsupportedOperationException("setName can only be called on a root variable");
+    }
+    
+    public Type getType() {
+        return field.getType();
+    }
+
+    public boolean isPrimitive() {
+        return field.getType().isPrimitive();
+    }
+
+    public boolean isRestartable() {
+        return !isPrimitive();
+    }
+
+    public Field getField() {
+        return field;
+    }
+    
+    protected abstract AbstractDataNode getParentNode();
+
+    /**
+     * create a String representation of this node. If the node has a value,
+     * then uses the String representation of that value. Otherwise, generates a
+     * text description.
+     */
+    public String toString() {
+        return toDisplayableString();
+    }
+
+    private String toDisplayableString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getDisplayableName());
+        Path p = getPathFromRoot();
+        if (!p.isEmpty()) {
+            if (!p.isArrayIndex(0)) {
+                sb.append(".");
+            }
+            sb.append(p.toString());
+        }
+        sb.append(":");
+        Type type = getType();
+        String strtype = type.toString();
+        if (type.isArray() && isClosed()) {
+            strtype = strtype.replace("[]", "[" + this.arraySize() + "]");
+        }
+        sb.append(strtype);
+        Object value = getRawValue();
+        
+        if (value != null) {
+            sb.append(" = ");
+            if (value instanceof Throwable) {
+                sb.append(value.getClass().getName());
+            }
+            else {
+                sb.append(value);
+            }
+        }
+        if (isClosed()) {
+            sb.append(" - Closed");
+        }
+        else {
+            sb.append(" - Open");
+        }
+        return sb.toString();
+    }
+    
+    protected abstract Object getRawValue();
+    
+    protected int arraySize() {
+        return -1;
+    }
+
+    public String getIdentifyingString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(this.getClass().getName());
+
+        sb.append(" identifier ");
+        sb.append(this.getIdentifier());
+
+        sb.append(" type ");
+        sb.append(getType());
+
+        Object value = getRawValue();
+        if (value == null) {
+            sb.append(" with no value at dataset=");
+        }
+        else if (value instanceof Throwable) {
+            sb.append(" containing throwable ");
+            sb.append(value.getClass());
+            sb.append(" dataset=");
+        }
+        else {
+            sb.append(" value=");
+            sb.append(value.toString());
+            sb.append(" dataset=");
+        }
+
+        sb.append(getDisplayableName());
+
+        if (!Path.EMPTY_PATH.equals(getPathFromRoot())) {
+            sb.append(" path=");
+            sb.append(getPathFromRoot().toString());
+        }
+
+        if (isClosed()) {
+            sb.append(" (closed)");
+        }
+        else {
+            sb.append(" (not closed)");
+        }
+
+        return sb.toString();
+    }
+
+    public String getDisplayableName() {
+        return getName();
+    }
+    
+    public String getFullName() {
+        String name = getDisplayableName();
+        Path p = getPathFromRoot();
+        if (p.isEmpty()) {
+            return name;
+        }
+        else {
+            return name + "." + p;
+        }
+    }
+        
+    public DSHandle getField(Path path) throws InvalidPathException {
+        if (path.isEmpty()) {
+            return this;
+        }
+        try {
+            DSHandle handle = getField(path.getFirst());
+            
+            if (path.size() > 1) {
+                return handle.getField(path.butFirst());
+            }
+            else {
+                return handle;
+            }
+        }
+        catch (NoSuchFieldException e) {
+            throw new InvalidPathException(path, this);
+        }
+    }
+
+    @Override
+    public Collection<DSHandle> getAllFields() throws InvalidPathException, HandleOpenException {
+        throw new InvalidPathException("No fields");
+    }
+            
+    @Override
+    public DSHandle getField(Comparable<?> key) throws NoSuchFieldException {
+        throw new NoSuchFieldException("No fields");
+    }
+
+    public Map<Comparable<?>, DSHandle> getArrayValue() {
+        throw new RuntimeException("getArrayValue called on a non-array: " + this);
+    }
+
+    @Override
+    public Collection<Path> getFringePaths() throws HandleOpenException {
+        List<Path> list = new ArrayList<Path>();
+        getFringePaths(list, Path.EMPTY_PATH);
+        return list;
+    }
+    
+    protected abstract void getFringePaths(List<Path> list, Path myPath) throws HandleOpenException;
+
+    public Collection<DSHandle> getLeaves() throws HandleOpenException {
+        List<DSHandle> list = new ArrayList<DSHandle>();
+        getLeaves(list);
+        return list;
+    }
+            
+    protected abstract void getLeaves(List<DSHandle> list) throws HandleOpenException;
+
+    protected void postCloseActions() {
+        // closed
+        notifyListeners();
+        if (logger.isDebugEnabled()) {
+            logger.debug("closed " + this.getIdentifyingString());
+        }
+        // so because its closed, we can dump the contents
+
+        try {
+            if(provenance) {
+                logContent();
+            }
+        }
+        catch (Exception e) {
+            logger.warn("Exception whilst logging dataset content for " + this, e);
+        }
+        // TODO record retrospective provenance information for this dataset here
+        // we should do it at closing time because that's the point at which we
+        // know the dataset has its values (all the way down the tree) assigned.
+
+        // provenance-id for this dataset should have been assigned at creation time,
+        // though, so that we can refer to this dataset elsewhere before it is closed.
+
+        // is this method the only one called to set this.closed? or do subclasses
+        // or other methods ever change it?
+    }
+
+    public synchronized void logContent() {
+        String identifier = this.getIdentifier();
+        Path pathFromRoot = this.getPathFromRoot();
+        Type type = this.getType();
+        if (this.getPathFromRoot() != null) {
+            if (logger.isInfoEnabled()) {
+                logger.info("ROOTPATH dataset=" + identifier + " path=" + pathFromRoot);
+                if (this.getType().isPrimitive()) {
+                    logger.info("VALUE dataset=" + identifier + " VALUE=" + this.toString());
+                }
+            }
+
+            Mapper m = getActualMapper();
+
+            if (m != null) {
+                // TODO proper type here
+                // Not sure catching exception here is really the right thing to
+                // do here
+                // anyway - should perhaps only be trying to map leafnodes?
+                // Mapping
+                // non-leaf stuff is giving wierd paths anyway
+
+                // TODO this is perhaps an unpleasant way of finding if this is a file-backed
+                // leaf node or not
+                boolean filemapped = true;
+                
+                if (type.getName().equals("external")) {
+                    filemapped = false;
+                }
+                if (type.isPrimitive()) {
+                    filemapped = false;
+                }
+                if (type.isComposite()) {
+                    filemapped = false;
+                }
+
+                try {
+                    if (filemapped) {
+                        Object path = map();
+                        if (logger.isInfoEnabled()) {
+                            logger.info("FILENAME dataset=" + identifier + " filename=" + path);
+                        }
+                    }
+                }
+                catch (Exception e) {
+                    if (logger.isInfoEnabled()) {
+                        logger.info("NOFILENAME dataset=" + identifier);
+                    }
+                }
+            }
+        }
+
+        if (type.isComposite()) {
+            synchronized (this) {
+                try {
+                    for (DSHandle handle : this.getAllFields()) {
+                        AbstractDataNode node = (AbstractDataNode) handle;
+                        if (logger.isInfoEnabled()) {
+                            logger.info("CONTAINMENT parent=" + identifier + " child=" + node.getIdentifier());
+                        }
+                        node.logContent();
+                    }
+                }
+                catch (Exception e) {
+                    logger.warn("Exception caught while trying to log provenance data", e);
+                }
+            }
+        }
+    }
+	
+	private Mapper getActualMapper() {
+        return getRoot().getActualMapper();
+    }
+	
+	protected Path calculatePathFromRoot() {
+	    AbstractDataNode parent = (AbstractDataNode) this.getParent();
+        Path myPath;
+        if (parent != null) {
+            myPath = parent.getPathFromRoot();
+            return myPath.addLast(getField().getId(), parent.getField().getType().isArray());
+        }
+        else {
+            return Path.EMPTY_PATH;
+        }
+	}
+    
+    public Mapper getMapper() {
+        return ((AbstractDataNode) getRoot()).getMapper();
+    }
+    
+    protected InitMapper getInitMapper() {
+        Mapper m = getActualMapper();
+        if (m instanceof InitMapper) {
+            return (InitMapper) m;
+        }
+        else {
+            throw new IllegalStateException("Cannot get initialization mapper on initialized node");
+        }
+    }
+    
+    public boolean isInput() {
+        return getInitMapper().isInput();
+    }
+
+    public void setInput(boolean input) {
+        getInitMapper().setInput(input);
+    }
+    
+    @Override
+    public PhysicalFormat map(Path path) {
+        Mapper m = getMapper();
+        if (m == null) {
+            return null;
+        }
+        else {
+            Path p = getPathFromRoot().append(path);
+            return m.map(p);
+        }
+    }
+
+    @Override
+    public PhysicalFormat map() {
+        return map(Path.EMPTY_PATH);
+    }
+    
+    public synchronized String getIdentifier() {
+    	if (identifier == null) {
+   		    identifier = makeIdentifierURIString();
+    	}
+        return identifier;
+    }
+
+    String makeIdentifierURIString() {
+        datasetIDCounter++;
+        return DATASET_URI_PREFIX + datasetIDPartialID + ":" + datasetIDCounter;
+    }
+
+    public void addListener(DSHandleListener listener) {
+        throw new UnsupportedOperationException();
+    }
+    
+    public void addListener(FutureListener l) {
+        addListener(l, true);
+    }
+    
+    public void addListener(FutureListener l, boolean partialUpdates) {
+    	boolean closed;
+    	WaitingThreadsMonitor.addThread(l, this);
+    	synchronized(this) {
+    	    closed = addListener0(l);
+    	}
+    	if (closed) {
+    		notifyListeners();
+    	}
+    }
+    
+    protected abstract boolean addListener0(FutureListener l);
+    
+    protected abstract void notifyListeners();
+
+    public synchronized void clean() {
+        clean0();
+    }
+    
+    protected void clean0() {
+        field = null;
+    }
+    
+    public abstract void waitFor(Node who);
+    
+    public abstract void waitFor() throws OOBYield;
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureArrayDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureArrayDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureArrayDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,232 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import k.rt.FutureListener;
+
+import org.globus.cog.karajan.futures.FutureNotYetAvailable;
+import org.griphyn.vdl.karajan.WaitingThreadsMonitor;
+import org.griphyn.vdl.mapping.ClosedArrayEntries;
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.DependentException;
+import org.griphyn.vdl.mapping.HandleOpenException;
+import org.griphyn.vdl.mapping.InvalidPathException;
+import org.griphyn.vdl.mapping.MappingDependentException;
+import org.griphyn.vdl.mapping.OpenArrayEntries;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+
+public abstract class AbstractFutureArrayDataNode extends AbstractFutureDataNode implements ArrayHandle {
+    private Map<Comparable<?>, DSHandle> handles;
+    private RuntimeException exception;
+    private List<Comparable<?>> keyList;
+    
+    public AbstractFutureArrayDataNode(Field field) {
+        super(field);
+        handles = new HashMap<Comparable<?>, DSHandle>();
+    }
+    
+    public void addField(Comparable<?> key, DSHandle n) {
+        synchronized(this) {
+            handles.put(key, n);
+            addKey(key);
+        }
+        notifyListeners();
+    }
+    
+    private void addKey(Comparable<?> key) {
+        if (keyList != null) {
+            keyList.add(key);
+        }
+    }
+    
+        
+    @Override
+    public RootHandle getRoot() {
+        return null;
+    }
+
+    @Override
+    public DSHandle getParent() {
+        return null;
+    }
+
+    @Override
+    public Path getPathFromRoot() {
+        return null;
+    }
+
+    @Override
+    protected AbstractDataNode getParentNode() {
+        return null;
+    }
+    
+    @Override
+    public void addListener(FutureListener l, boolean partialUpdates) {
+        boolean shouldNotify;
+        WaitingThreadsMonitor.addThread(l, this);
+        synchronized(this) {
+            shouldNotify = addListener0(l);
+            if (keyList != null && partialUpdates) {
+                shouldNotify = true;
+            }
+        }
+        if (shouldNotify) {
+            notifyListeners();
+        }
+    }
+    
+    @Override
+    public Iterable<List<?>> entryList() {
+        synchronized(this) {
+            if (isClosed()) {
+                return new ClosedArrayEntries(getArrayValue());
+            }
+            else {
+                keyList = new ArrayList<Comparable<?>>(getArrayValue().keySet());
+                return new OpenArrayEntries(keyList, getArrayValue(), this);
+            }
+        }
+    }
+
+    @Override
+    protected Object getRawValue() {
+        return handles;
+    }
+        
+    public synchronized DSHandle getField(Comparable<?> key) throws NoSuchFieldException {
+        DSHandle handle = handles.get(key);
+        if (handle == null) {
+            if (isClosed()) {
+                throw new NoSuchFieldException(key.toString());
+            }
+            handle = createField(key);
+        }
+        return handle;
+    }
+
+    private DSHandle createField(Comparable<?> key) {
+        DSHandle h = NodeFactory.newNode(Field.Factory.createField(key, field.getType().itemType()), getRoot(), this);
+        synchronized(this) {
+            handles.put(key, h);
+            addKey(key);
+        }
+        notifyListeners();
+        return h;
+    }
+    
+    @Override
+    public Collection<DSHandle> getAllFields() throws InvalidPathException, HandleOpenException {
+        synchronized(this) {
+            if (!isClosed()) {
+                throw new HandleOpenException(this);
+            }
+        }
+        return handles.values();
+    }
+
+    protected void checkDataException() {
+        if (exception instanceof DependentException) {
+            throw (DependentException) exception;
+        }
+    }
+    
+    protected void checkMappingException() {
+        if (exception instanceof MappingDependentException) {
+            throw (MappingDependentException) exception;
+        }
+    }
+
+    public synchronized Object getValue() {
+        checkDataException();
+        return handles;
+    }
+    
+    public Map<Comparable<?>, DSHandle> getArrayValue() {
+        checkDataException();
+        return handles;
+    }
+    
+    @Override
+    public synchronized void closeShallow() {
+        super.closeShallow();
+        this.keyList = null;
+        if (handles.isEmpty()) {
+            handles = Collections.emptyMap();
+        }
+    }
+
+    @Override
+    public void closeDeep() {
+        closeShallow();
+        // closeShallow provides a synchronization point, so we know handles cannot be modified after that
+        for (DSHandle handle : handles.values()) {
+            handle.closeDeep();
+        }
+    }
+    
+    @Override
+    public void getFringePaths(List<Path> list, Path myPath) throws HandleOpenException {
+        checkMappingException();
+        if (!isClosed()) {
+            throw new FutureNotYetAvailable(this);
+        }
+        for (Map.Entry<Comparable<?>, DSHandle> e : handles.entrySet()) {
+            AbstractDataNode child = (AbstractDataNode) e.getValue();
+            Path fullPath = myPath.addLast(e.getKey(), true);
+            child.getFringePaths(list, fullPath);
+        }
+    }
+    
+    @Override
+    protected void getLeaves(List<DSHandle> list) throws HandleOpenException {
+        checkMappingException();
+        if (!isClosed()) {
+            throw new HandleOpenException(this);
+        }
+        for (DSHandle h : handles.values()) {
+            AbstractDataNode child = (AbstractDataNode) h;
+            child.getLeaves(list);
+        }
+    }
+    
+    public boolean isArray() {
+        return true;
+    }
+    
+    @Override
+    protected void clean0() {
+        for (DSHandle h : handles.values()) {
+            ((AbstractDataNode) h).clean0();
+        }
+        handles = null;
+        super.clean0();
+    }
+
+    @Override
+    protected void checkNoValue() {
+        if (exception != null) {
+            throw exception;
+        }
+    }
+    
+    @Override
+    public int arraySize() {
+        return handles.size();
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,155 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import k.rt.FutureListener;
+import k.thr.Yield;
+
+import org.globus.cog.karajan.compiled.nodes.Node;
+import org.globus.cog.karajan.futures.FutureNotYetAvailable;
+import org.griphyn.vdl.karajan.WaitingThreadsMonitor;
+import org.griphyn.vdl.mapping.OOBYield;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+
+public abstract class AbstractFutureDataNode extends AbstractDataNode {
+	private boolean closed;
+	private List<FutureListener> listeners;
+	private int writeRefCount;
+
+	public AbstractFutureDataNode(Field field) {
+	    super(field);
+    }
+	
+	@Override
+    protected boolean addListener0(FutureListener l) {
+        if (this.listeners == null) {
+            this.listeners = new ArrayList<FutureListener>();
+        }
+        this.listeners.add(l);
+        return this.isClosed();
+    }
+	
+	@Override
+	protected void notifyListeners() {
+        List<FutureListener> l;
+        synchronized(this) {
+            l = this.listeners;
+            this.listeners = null;
+        }
+        if (l != null) {
+            for (FutureListener ll : l) {
+                ll.futureUpdated(this);
+                WaitingThreadsMonitor.removeThread(ll);
+            }
+        }
+    }
+
+    @Override
+    public boolean isClosed() {
+        return closed;
+    }
+    
+    protected void setClosed(boolean closed) {
+        this.closed = closed;
+    }
+    
+    public void closeShallow() {
+        synchronized(this) {
+            if (this.closed) {
+                return;
+            }
+            this.closed = true;
+        }
+        postCloseActions();
+    }
+    
+    public void closeDeep() {
+        closeShallow();
+    }
+    
+    public void setValue(Object value) {
+        throw new IllegalArgumentException(this.getFullName() 
+            + " cannot set the value of a " + this.getType());
+    }
+    
+    @Override
+    protected void clean0() {
+        listeners = null;
+        super.clean0();
+    }
+    
+    @Override
+    public synchronized void setWriteRefCount(int count) {
+        this.writeRefCount = count;
+    }
+
+    @Override
+    public synchronized int updateWriteRefCount(int delta) {
+        this.writeRefCount += delta;
+       
+        if (this.writeRefCount < 0) {
+            throw new IllegalArgumentException("Reference count mismatch for " + this + ". Count is " + this.writeRefCount);
+        }
+                        
+        if (logger.isDebugEnabled()) {
+            logger.debug(this + " writeRefCount " + this.writeRefCount);
+        }
+        if (this.writeRefCount == 0) {
+            if (variableTracer.isEnabled()) {
+                RootHandle root = getRoot();
+                variableTracer.trace(root.getThread(), root.getLine(), getDisplayableName() + " CLOSE write ref count is zero");
+            }
+            closeDeep();
+        }
+        return this.writeRefCount;
+    }
+    
+    @Override
+    public synchronized void waitFor(Node who) {
+        if (!closed) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("Waiting for " + this);
+            }
+            
+            Yield y = new FutureNotYetAvailable(this);
+            y.getState().addTraceElement(who);
+            throw y;
+        }
+        else {
+            if (logger.isDebugEnabled()) {
+                logger.debug("Do not need to wait for " + this);
+            }
+            checkNoValue();
+        }
+    }
+    
+    @Override
+    public synchronized void waitFor() throws OOBYield {
+        if (!closed) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("Waiting for " + this);
+            }
+            
+            throw new OOBYield(new FutureNotYetAvailable(this), this);
+        }
+        else {
+            if (logger.isDebugEnabled()) {
+                logger.debug("Do not need to wait for " + this);
+            }
+            checkNoValue();
+        }
+    }
+    
+    protected abstract void checkNoValue();
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureMappedSingleDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureMappedSingleDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureMappedSingleDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,43 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import java.util.List;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.HandleOpenException;
+import org.griphyn.vdl.mapping.Mapper;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.type.Field;
+
+public abstract class AbstractFutureMappedSingleDataNode extends AbstractFutureNonCompositeDataNode {
+
+    public AbstractFutureMappedSingleDataNode(Field field) {
+        super(field);    
+    }
+    
+    public void getFringePaths(List<Path> list, Path myPath) throws HandleOpenException {
+        list.add(myPath);
+    }
+    
+    @Override
+    protected void getLeaves(List<DSHandle> list) throws HandleOpenException {
+        list.add(this);
+    }
+    
+    @Override
+    protected void clean0() {
+        Mapper mapper = getMapper();
+        if (mapper != null) {
+            mapper.clean(getPathFromRoot());
+        }
+        super.clean0();
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureNonCompositeDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureNonCompositeDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureNonCompositeDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,94 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import org.griphyn.vdl.mapping.DependentException;
+import org.griphyn.vdl.mapping.MappingDependentException;
+import org.griphyn.vdl.mapping.MissingDataException;
+import org.griphyn.vdl.type.Field;
+
+
+public abstract class AbstractFutureNonCompositeDataNode extends AbstractFutureDataNode {
+    private Object value;
+
+    public AbstractFutureNonCompositeDataNode(Field field) {
+        super(field);
+    }
+
+    @Override
+    protected Object getRawValue() {
+        return value;
+    }
+    
+    protected void checkDataException() {
+        if (value instanceof DependentException) {
+            throw (DependentException) value;
+        }
+    }
+
+    protected void checkMappingException() {
+        if (value instanceof MappingDependentException) {
+            throw (MappingDependentException) value;
+        }
+    }
+
+    @Override
+    public synchronized Object getValue() {
+        checkNoValue();
+        checkDataException();
+        return value;
+    }
+    
+    @Override
+    protected void checkNoValue() {
+        if (value == null) {
+            AbstractDataNode parent = getParentNode();
+            if (parent != null && parent.getType().isArray()) {
+                throw new IndexOutOfBoundsException("Invalid index [" + field.getId() + "] for " + parent.getFullName());
+            }
+            else if (getType().isPrimitive()) {
+                throw new RuntimeException(getFullName() + " has no value");
+            }
+            else {
+                throw new MissingDataException(this, map());
+            }
+        }
+        if (value instanceof RuntimeException) {
+            throw (RuntimeException) value;
+        }
+    }
+    
+    public void setValue(Object value) {
+        synchronized(this) {
+            if (isClosed()) {
+                throw new IllegalArgumentException(this.getFullName() 
+                        + " is closed with a value of " + this.value);
+            }
+            if (this.value != null) {
+                throw new IllegalArgumentException(this.getFullName() 
+                        + " is already assigned with a value of " + this.value);
+            }
+        
+            this.value = value;
+            this.setClosed(true);
+        }
+        postCloseActions();
+    }
+    
+    public boolean isArray() {
+        return false;
+    }
+    
+    @Override
+    protected void clean0() {
+        value = null;
+        super.clean0();
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFuturePrimitiveDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFuturePrimitiveDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFuturePrimitiveDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,33 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import java.util.List;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.HandleOpenException;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.type.Field;
+
+public abstract class AbstractFuturePrimitiveDataNode extends AbstractFutureNonCompositeDataNode {
+    
+    public AbstractFuturePrimitiveDataNode(Field field) {
+        super(field);
+    }
+
+    public void getFringePaths(List<Path> list, Path parentPath) throws HandleOpenException {
+        // only mappable paths
+    }
+    
+    @Override
+    protected void getLeaves(List<DSHandle> list) throws HandleOpenException {
+        // only mappable paths
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureStructDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureStructDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/AbstractFutureStructDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,142 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.DependentException;
+import org.griphyn.vdl.mapping.HandleOpenException;
+import org.griphyn.vdl.mapping.MappingDependentException;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+import org.griphyn.vdl.type.Type;
+
+public abstract class AbstractFutureStructDataNode extends AbstractFutureDataNode {
+    private DSHandle[] fields;
+    private RuntimeException exception;
+    
+    public AbstractFutureStructDataNode(Field field, RootHandle root) {
+        super(field);
+        fields = new DSHandle[field.getType().getFields().size()];
+    }
+    
+    @Override
+    public void initialize() {
+        super.initialize();
+        createFieldNodes();
+    }
+
+    private void createFieldNodes() {
+        for (Field f : field.getType().getFields()) {
+            try {
+                setField((String) f.getId(), NodeFactory.newNode(f, getRoot(), this));
+            }
+            catch (NoSuchFieldException e) {
+                throw new RuntimeException("Type inconsistency detected for field " + f);
+            }
+        }
+    }
+
+    protected void setField(String name, DSHandle n) throws NoSuchFieldException {
+        fields[field.getType().getFieldIndex(name)] = n;
+    }
+        
+    @Override
+    protected Object getRawValue() {
+        return null;
+    }
+    
+    @Override
+    public Object getValue() {
+        return Arrays.asList(fields);
+    }
+    
+    protected void checkDataException() {
+        if (exception instanceof DependentException) {
+            throw (DependentException) exception;
+        }
+    }
+    
+    protected void checkMappingException() {
+        if (exception instanceof MappingDependentException) {
+            throw (MappingDependentException) exception;
+        }
+    }
+
+    @Override
+    public synchronized DSHandle getField(Comparable<?> key) throws NoSuchFieldException {
+        return fields[field.getType().getFieldIndex((String) key)];
+    }
+    
+    @Override
+    public void closeDeep() {
+        closeShallow();
+        for (DSHandle handle : fields) {
+            handle.closeDeep();
+        }
+    }
+    
+    @Override
+    public void getFringePaths(List<Path> list, Path myPath) throws HandleOpenException {
+        checkMappingException();
+        Type t = field.getType();
+        for (Field f : t.getFields()) {
+            AbstractDataNode child;
+            try {
+                child = (AbstractDataNode) getField(f.getId());
+            }
+            catch (Exception e) {
+                throw new RuntimeException("Structure inconsistency detected for field " + f);
+            }
+            Path fullPath = myPath.addLast(f.getId());
+            child.getFringePaths(list, fullPath);
+        }
+    }
+    
+    @Override
+    protected void getLeaves(List<DSHandle> list) throws HandleOpenException {
+        checkMappingException();
+        Type t = field.getType();
+        for (Field f : t.getFields()) {
+            AbstractDataNode child;
+            try {
+                child = (AbstractDataNode) getField(f.getId());
+            }
+            catch (Exception e) {
+                throw new RuntimeException("Structure inconsistency detected for field " + f);
+            }
+            child.getLeaves(list);
+        }
+    }
+    
+    public boolean isArray() {
+        return false;
+    }
+    
+    @Override
+    protected void clean0() {
+        for (DSHandle h : fields) {
+            ((AbstractDataNode) h).clean0();
+        }
+        fields = null;
+        exception = null;
+        super.clean0();
+    }
+    
+    @Override
+    protected void checkNoValue() {
+        if (exception != null) {
+            throw exception;
+        }
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/ArrayHandle.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/ArrayHandle.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/ArrayHandle.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,22 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 30, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import java.util.List;
+
+import k.rt.Future;
+
+import org.griphyn.vdl.mapping.DSHandle;
+
+public interface ArrayHandle extends DSHandle, Future {
+    Iterable<List<?>> entryList();
+    
+    public int arraySize();
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/ClosedArrayDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/ClosedArrayDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/ClosedArrayDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,47 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import java.util.List;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+
+public class ClosedArrayDataNode extends AbstractClosedArrayDataNode {
+    private RootHandle root;
+    private AbstractDataNode parent;
+    private Path pathFromRoot;
+    
+    protected ClosedArrayDataNode(Field field, RootHandle root, AbstractDataNode parent, List<?> values) {
+        super(field, values);
+        this.root = root;
+        this.parent = parent;
+        this.pathFromRoot = parent.getPathFromRoot().addLast(field.getId(), parent.getType().isArray());
+    }
+    
+    public RootHandle getRoot() {
+        return root;
+    }
+    
+    public DSHandle getParent() {
+        return parent;
+    }
+    
+    public AbstractDataNode getParentNode() {
+        return parent;
+    }
+
+    @Override
+    public Path getPathFromRoot() {
+        return pathFromRoot;
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/ClosedMappedSingleDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/ClosedMappedSingleDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/ClosedMappedSingleDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,45 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+
+public class ClosedMappedSingleDataNode extends AbstractClosedMappedSingleDataNode {
+    private RootHandle root;
+    private AbstractDataNode parent;
+    private Path pathFromRoot;
+    
+    protected ClosedMappedSingleDataNode(Field field, RootHandle root, AbstractDataNode parent) {
+        super(field, AbstractDataNode.FILE_VALUE);
+        this.root = root;
+        this.parent = parent;
+        this.pathFromRoot = parent.getPathFromRoot().addLast(field.getId(), parent.getType().isArray());
+    }
+    
+    public RootHandle getRoot() {
+        return root;
+    }
+    
+    public DSHandle getParent() {
+        return parent;
+    }
+    
+    public AbstractDataNode getParentNode() {
+        return parent;
+    }
+    
+    @Override
+    public Path getPathFromRoot() {
+        return pathFromRoot;
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/ClosedPrimitiveDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/ClosedPrimitiveDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/ClosedPrimitiveDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,45 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+
+public class ClosedPrimitiveDataNode extends AbstractClosedMappedSingleDataNode {
+    private RootHandle root;
+    private AbstractDataNode parent;
+    private Path pathFromRoot;
+    
+    protected ClosedPrimitiveDataNode(Field field, RootHandle root, AbstractDataNode parent, Object value) {
+        super(field, value);
+        this.root = root;
+        this.parent = parent;
+        this.pathFromRoot = parent.getPathFromRoot().addLast(field.getId(), parent.getType().isArray());
+    }
+    
+    public RootHandle getRoot() {
+        return root;
+    }
+    
+    public DSHandle getParent() {
+        return parent;
+    }
+    
+    public AbstractDataNode getParentNode() {
+        return parent;
+    }
+    
+    @Override
+    public Path getPathFromRoot() {
+        return pathFromRoot;
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/ExternalDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/ExternalDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/ExternalDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2012 University of Chicago
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.griphyn.vdl.mapping.nodes;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import k.thr.LWThread;
+
+import org.apache.log4j.Logger;
+import org.griphyn.vdl.karajan.Loader;
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.HandleOpenException;
+import org.griphyn.vdl.mapping.InvalidPathException;
+import org.griphyn.vdl.mapping.Mapper;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+import org.griphyn.vdl.type.Types;
+import org.griphyn.vdl.type.impl.FieldImpl;
+
+public class ExternalDataNode extends AbstractFutureNonCompositeDataNode implements RootHandle {
+
+	static final String DATASET_URI_PREFIX = "dataset:external:";
+
+	public static final Logger logger = Logger.getLogger(ExternalDataNode.class);
+	
+	private static long datasetIDCounter = 850000000000l;
+
+	private static final String datasetIDPartialID = Loader.getUUID();
+	
+    // previously in mapper params
+    private int line = -1;
+    private LWThread thread;
+    private boolean input;
+
+	
+	public ExternalDataNode(String name) {
+	    super(new FieldImpl(name, Types.EXTERNAL));
+	}
+	
+	public ExternalDataNode(Field field) {
+        super(field);
+    }
+
+    public int getLine() {
+        return line;
+    }
+
+    public void setLine(int line) {
+        this.line = line;
+    }
+
+    public boolean isInput() {
+        return input;
+    }
+
+    public void setInput(boolean input) {
+        this.input = input;
+    }
+
+    public void setThread(LWThread thread) {
+        this.thread = thread;
+    }
+
+    public LWThread getThread() {
+        return thread;
+    }
+
+	public String getName() {
+        return (String) getField().getId();
+    }
+	
+	@Override
+    public void setName(String name) {
+        getField().setId(name);
+    }
+
+	@Override
+    public void init(Mapper mapper) {
+    }
+
+    @Override
+    public void mapperInitialized(Mapper mapper) {
+    }
+
+    public boolean isRestartable() {
+		return true;
+	}
+
+	public RootHandle getRoot() {
+		return this;
+	}
+
+	public DSHandle getField(Path path) throws InvalidPathException {
+		if (path.isEmpty()) {
+			return this;
+		} 
+		else {
+			throw new InvalidPathException(path, this);
+		}
+	}
+	
+	protected void getFields(List<DSHandle> fields, Path path) throws InvalidPathException {
+	    // nothing
+	}
+
+	public void set(DSHandle handle) {
+		throw new UnsupportedOperationException(this.getDisplayableName() + " is an external dataset and cannot be set");
+	}
+
+	public Map<Comparable<?>, DSHandle> getArrayValue() {
+	    throw new UnsupportedOperationException("cannot get value of external dataset");
+	}
+
+	public boolean isArray() {
+		return false;
+	}
+
+	public Collection<Path> getFringePaths() throws HandleOpenException {
+	    return Collections.singletonList(Path.EMPTY_PATH);
+	}
+
+	public Path getPathFromRoot() {
+		return Path.EMPTY_PATH;
+	}
+
+	public Mapper getMapper() {
+		return null;
+	}
+
+	protected String makeIdentifierURIString() {
+		datasetIDCounter++;
+		return DATASET_URI_PREFIX + datasetIDPartialID + ":" + datasetIDCounter; 
+	}
+
+	public DSHandle createDSHandle(String fieldName) {
+	    throw new UnsupportedOperationException("cannot create new field in external dataset");
+	}
+
+	public DSHandle getParent() {
+	    return null;
+	}
+
+    @Override
+    protected AbstractDataNode getParentNode() {
+        return null;
+    }
+
+    @Override
+    public synchronized void closeDeep() {
+        if (!this.isClosed()) {
+            /*
+             * Need to override this and set a value since 
+             * this is skipped by the normal stageout mechanism which
+             * does that
+             */
+            this.setValue(FILE_VALUE);
+        }
+    }
+
+    @Override
+    public Mapper getActualMapper() {
+        return null;
+    }
+
+    @Override
+    public void closeArraySizes() {
+    }
+
+    @Override
+    protected void getFringePaths(List<Path> list, Path myPath) throws HandleOpenException {
+    }
+
+    @Override
+    protected void getLeaves(List<DSHandle> list) throws HandleOpenException {
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/FutureArrayDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/FutureArrayDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/FutureArrayDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,53 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+
+public class FutureArrayDataNode extends AbstractFutureArrayDataNode {
+    private RootHandle root;
+    private AbstractDataNode parent;
+    private Path pathFromRoot;
+    
+    protected FutureArrayDataNode(Field field, RootHandle root, AbstractDataNode parent) {
+        super(field);
+        this.root = root;
+        this.parent = parent;
+        this.pathFromRoot = calculatePathFromRoot();
+    }
+    
+    public RootHandle getRoot() {
+        return root;
+    }
+    
+    public DSHandle getParent() {
+        return parent;
+    }
+    
+    public AbstractDataNode getParentNode() {
+        return parent;
+    }
+    
+    @Override
+    public Path getPathFromRoot() {
+        return pathFromRoot;
+    }
+    
+    @Override
+    protected void clean0() {
+        super.clean0();
+        root = null;
+        parent = null;
+        pathFromRoot = null;
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/FutureMappedSingleDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/FutureMappedSingleDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/FutureMappedSingleDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,66 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import java.util.List;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.HandleOpenException;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+
+public class FutureMappedSingleDataNode extends AbstractFutureNonCompositeDataNode {
+    private RootHandle root;
+    private AbstractDataNode parent;
+    private Path pathFromRoot;
+    
+    protected FutureMappedSingleDataNode(Field field, RootHandle root, AbstractDataNode parent) {
+        super(field);
+        this.root = root;
+        this.parent = parent;
+        this.pathFromRoot = calculatePathFromRoot();
+    }
+    
+    public RootHandle getRoot() {
+        return root;
+    }
+    
+    public DSHandle getParent() {
+        return parent;
+    }
+    
+    public AbstractDataNode getParentNode() {
+        return parent;
+    }
+    
+    @Override
+    public Path getPathFromRoot() {
+        return pathFromRoot;
+    }
+    
+    @Override
+    protected void getFringePaths(List<Path> list, Path myPath) throws HandleOpenException {
+        list.add(myPath);
+    }
+
+    @Override
+    protected void getLeaves(List<DSHandle> list) throws HandleOpenException {
+        list.add(this);
+    }
+    
+    @Override
+    protected void clean0() {
+        super.clean0();
+        root = null;
+        parent = null;
+        pathFromRoot = null;
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/FuturePrimitiveDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/FuturePrimitiveDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/FuturePrimitiveDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,64 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import java.util.List;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.HandleOpenException;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+
+public class FuturePrimitiveDataNode extends AbstractFutureNonCompositeDataNode {
+    private RootHandle root;
+    private AbstractDataNode parent;
+    private Path pathFromRoot; 
+    
+    protected FuturePrimitiveDataNode(Field field, RootHandle root, AbstractDataNode parent) {
+        super(field);
+        this.root = root;
+        this.parent = parent;
+        this.pathFromRoot = calculatePathFromRoot();
+    }
+    
+    public RootHandle getRoot() {
+        return root;
+    }
+    
+    public DSHandle getParent() {
+        return parent;
+    }
+    
+    public AbstractDataNode getParentNode() {
+        return parent;
+    }
+    
+    @Override
+    public Path getPathFromRoot() {
+        return pathFromRoot;
+    }
+    
+    @Override
+    protected void getFringePaths(List<Path> list, Path myPath) throws HandleOpenException {
+    }
+
+    @Override
+    protected void getLeaves(List<DSHandle> list) throws HandleOpenException {
+    }
+    
+    @Override
+    protected void clean0() {
+        super.clean0();
+        root = null;
+        parent = null;
+        pathFromRoot = null;
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/FutureStructDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/FutureStructDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/FutureStructDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,53 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+
+public class FutureStructDataNode extends AbstractFutureStructDataNode {
+    private RootHandle root;
+    private AbstractDataNode parent;
+    private Path pathFromRoot;
+    
+    protected FutureStructDataNode(Field field, RootHandle root, AbstractDataNode parent) {
+        super(field, root);
+        this.root = root;
+        this.parent = parent;
+        this.pathFromRoot = calculatePathFromRoot();
+    }
+    
+    public RootHandle getRoot() {
+        return root;
+    }
+    
+    public DSHandle getParent() {
+        return parent;
+    }
+    
+    public AbstractDataNode getParentNode() {
+        return parent;
+    }
+    
+    @Override
+    public Path getPathFromRoot() {
+        return pathFromRoot;
+    }
+    
+    @Override
+    protected void clean0() {
+        super.clean0();
+        root = null;
+        parent = null;
+        pathFromRoot = null;
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/InitMapper.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/InitMapper.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/InitMapper.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,292 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 30, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import k.rt.Future;
+import k.rt.FutureListener;
+
+import org.apache.log4j.Logger;
+import org.globus.cog.karajan.futures.FutureNotYetAvailable;
+import org.griphyn.vdl.karajan.lib.Tracer;
+import org.griphyn.vdl.mapping.AbsFile;
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.DependentException;
+import org.griphyn.vdl.mapping.DuplicateMappingChecker;
+import org.griphyn.vdl.mapping.FileSystemLister;
+import org.griphyn.vdl.mapping.HandleOpenException;
+import org.griphyn.vdl.mapping.InvalidPathException;
+import org.griphyn.vdl.mapping.Mapper;
+import org.griphyn.vdl.mapping.MappingDependentException;
+import org.griphyn.vdl.mapping.NotCompositeException;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.PhysicalFormat;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Type;
+
+public class InitMapper implements Mapper, FutureListener {
+    public static final Logger logger = Logger.getLogger(InitMapper.class);
+    
+    protected static final Tracer variableTracer = Tracer.getTracer("VARIABLE");
+    
+    private Mapper mapper;
+    private boolean input;
+    private AbstractDataNode waitingMapperParam;
+    private RootHandle node;
+    private DuplicateMappingChecker dmc;
+    
+    public InitMapper(DuplicateMappingChecker dmc) {
+        this.dmc = dmc;
+    }
+    
+    @Override
+    public PhysicalFormat map(Path path) {
+        return null;
+    }
+
+    @Override
+    public boolean exists(Path path) {
+        return false;
+    }
+
+    @Override
+    public Collection<Path> existing() {
+        return null;
+    }
+
+    @Override
+    public Collection<Path> existing(FileSystemLister l) {
+        return null;
+    }
+
+    @Override
+    public boolean isStatic() {
+        return false;
+    }
+
+    @Override
+    public boolean canBeRemapped(Path path) {
+        return false;
+    }
+
+    @Override
+    public void remap(Path path, Mapper sourceMapper, Path sourcePath) {
+    }
+
+    @Override
+    public void clean(Path paths) {
+    }
+
+    @Override
+    public boolean isPersistent(Path path) {
+        return false;
+    }
+
+    @Override
+    public Set<String> getSupportedParamNames() {
+        return null;
+    }
+
+    @Override
+    public void setParameters(Map<String, Object> params) {
+    }
+
+    @Override
+    public void initialize(RootHandle node) {
+        synchronized(node) {
+            this.node = node;
+            waitingMapperParam = mapper.getFirstOpenParameter();
+            if (waitingMapperParam != null) {
+                waitingMapperParam.addListener(this);
+                if (variableTracer.isEnabled()) {
+                    variableTracer.trace(node.getThread(), node.getLine(), node.getName() + " WAIT " 
+                        + Tracer.getVarName(waitingMapperParam));
+                }
+                return;
+            }
+            
+            // initialized means that this data has its mapper initialized
+            // this should be called before checkInputs because the latter
+            // may trigger calls to things that try to access this data node's
+            // mapper
+            mapper.initialize(node);
+            node.mapperInitialized(mapper);
+            try {
+                checkInputs(node, dmc);
+            }
+            catch (DependentException e) {
+                node.setValue(new MappingDependentException(node, e));
+            }
+        }
+    }
+
+    @Override
+    public void futureUpdated(Future fv) {
+        initialize(node);
+    }
+
+    @Override
+    public void setBaseDir(String baseDir) {
+        mapper.setBaseDir(baseDir);
+    }
+
+    @Override
+    public AbstractDataNode getFirstOpenParameter() {
+        return null;
+    }
+
+    @Override
+    public Collection<AbsFile> getPattern(Path path, Type type) {
+        return null;
+    }
+
+    public boolean isInput() {
+        return input;
+    }
+
+    public void setInput(boolean input) {
+        this.input = input;
+    }
+
+    public Mapper getMapper() {
+        synchronized(node) {
+            if (waitingMapperParam != null) {
+                throw new FutureNotYetAvailable(waitingMapperParam);
+            }
+            else {
+                return mapper;
+            }
+        }
+    }
+    
+    public void setMapper(Mapper mapper) {
+        this.mapper = mapper;
+    }
+    
+    public void checkInputs(RootHandle root, DuplicateMappingChecker dmc) {
+        Mapper mapper = root.getActualMapper();
+        if (input) {
+            addExisting(mapper.existing(), mapper, root, root);
+            checkConsistency(root, root, dmc);
+        }
+        else if (mapper.isStatic()) {
+            if (root.isClosed()) {
+                // this means that code that would have used this variable is already done
+                // which can happen in cases such as if(false) {a = ...}
+                return;
+            }
+            if (!root.getType().isComposite()) {
+                return;
+            }
+            // Static mappers are (array) mappers which know the size of
+            // an array statically. A good example is the fixed array mapper
+            if (logger.isDebugEnabled()) {
+                logger.debug("mapper: " + mapper);
+            }
+            for (Path p : mapper.existing()) {
+                try {
+                    // Try to get the path in order to check that the 
+                    // path is valid - we'll get an exception if not
+                    DSHandle h = root.getField(p);
+                    if (variableTracer.isEnabled()) {
+                        variableTracer.trace(root.getThread(), root.getLine(), 
+                            root.getName() + " MAPPING " + p + ", " + mapper.map(p));
+                    }
+                }
+                catch (InvalidPathException e) {
+                    throw new IllegalStateException
+                    ("mapper.existing() returned a path " + 
+                    " that it cannot subsequently map: " + 
+                    " root: " + root + " path: " + p);
+                }
+            }
+            if (root.isArray()) {
+                root.closeArraySizes();
+            }
+            checkConsistency(root, root, dmc);
+        }
+    }
+
+    public static void addExisting(Collection<Path> existing, Mapper mapper, RootHandle root, DSHandle var) {
+        boolean any = false;
+        for (Path p : existing) {
+            try {
+                DSHandle field = var.getField(p);
+                field.setValue(AbstractDataNode.FILE_VALUE);
+                if (variableTracer.isEnabled()) {
+                    variableTracer.trace(root.getThread(), root.getLine(), 
+                        root.getName() + " MAPPING " + p + ", " + mapper.map(p));
+                }
+                any = true;
+            }
+            catch (InvalidPathException e) {
+                throw new IllegalStateException("Structure of mapped data is " +
+                        "incompatible with the mapped variable type: " + e.getMessage());
+            }
+            catch (NotCompositeException e) {
+                throw new IllegalStateException("Cannot map multiple files to variable '" + 
+                    e.getDataNode().getFullName() + "' of non composite type '" + 
+                    e.getDataNode().getType() + "'");
+            }
+        }
+        var.closeDeep();
+        if (!any && variableTracer.isEnabled()) {
+            variableTracer.trace(root.getThread(), root.getLine(), 
+                root.getName() + " MAPPING no files found");
+        }
+    }
+
+    public void checkConsistency(RootHandle root, DSHandle handle, DuplicateMappingChecker dmc) {
+        if (handle.getType().isArray()) {
+            // any number of indices is ok
+            try {
+                for (DSHandle dh : handle.getAllFields()) {
+                    checkConsistency(root, dh, dmc);
+                }
+            }
+            catch (HandleOpenException e) {
+                // TODO init() should throw some checked exception
+                throw new RuntimeException("Mapper consistency check failed for " + handle
+                        + ". A HandleOpenException was thrown during consistency checking for "+e.getSource(), e);
+            }
+            catch (InvalidPathException e) {
+                e.printStackTrace();
+            }
+        }
+        else {
+            // all fields must be present
+            Type type = handle.getType();
+            if (!type.isPrimitive() && !type.isComposite()) {
+                // mapped. Feed the DMC.
+                PhysicalFormat f = root.getActualMapper().map(handle.getPathFromRoot());
+                if (input) {
+                    dmc.addRead(f, handle);
+                }
+                else {
+                    dmc.addWrite(f, handle);
+                }
+            }
+            for (String fieldName : type.getFieldNames()) {
+                Path fieldPath = Path.parse(fieldName);
+                try {
+                    checkConsistency(root, handle.getField(fieldPath), dmc);
+                }
+                catch (InvalidPathException e) {
+                    throw new RuntimeException("Data set initialization failed for " + handle
+                            + ". Missing required field: " + fieldName);
+                }
+            }
+        }
+    }
+
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/NodeFactory.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/NodeFactory.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/NodeFactory.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,99 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import java.util.List;
+
+import org.griphyn.vdl.mapping.DependentException;
+import org.griphyn.vdl.mapping.DuplicateMappingChecker;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+import org.griphyn.vdl.type.Type;
+
+
+public class NodeFactory {
+    public static AbstractDataNode newNode(Field f, RootHandle root, AbstractDataNode parent) {
+        AbstractDataNode n;
+        Type t = f.getType();
+        if (t.isPrimitive()) {
+            n = new FuturePrimitiveDataNode(f, root, parent);
+        }
+        else if (!t.isComposite()) {
+            n = new FutureMappedSingleDataNode(f, root, parent);
+        }
+        else if (t.isArray()) {
+            n = new FutureArrayDataNode(f, root, parent);
+        }
+        else {
+            n = new FutureStructDataNode(f, root, parent);
+        }
+        n.initialize();
+        return n;
+    }
+    
+    public static AbstractDataNode newNode(Field f, RootHandle root, AbstractDataNode parent, Object value) {
+        AbstractDataNode n;
+        Type t = f.getType();
+        if (t.isPrimitive()) {
+            return new ClosedPrimitiveDataNode(f, root, parent, value);
+        }
+        else {
+            throw new IllegalArgumentException();
+        }
+    }
+    
+    public static AbstractDataNode newRoot(Field f, Object value) {
+        Type t = f.getType();
+        if (t.isPrimitive()) {
+            return new RootClosedPrimitiveDataNode(f, value);
+        }
+        else if (t.isArray() && t.itemType().isPrimitive()){
+            return new RootClosedArrayDataNode(f, (List<?>) value, null);
+        }
+        else {
+        	throw new IllegalArgumentException();
+        }
+    }
+    
+    public static AbstractDataNode newRoot(Field f, DependentException e) {
+        Type t = f.getType();
+        if (t.isPrimitive()) {
+            return new RootClosedPrimitiveDataNode(f, e);
+        }
+        else {
+            throw new IllegalArgumentException();
+        }
+    }
+    
+    public static RootHandle newOpenRoot(Field f, DuplicateMappingChecker dmc) {
+        Type t = f.getType();
+        if (t.isPrimitive()) {
+            return new RootFuturePrimitiveDataNode(f);
+        }
+        else if (t.isArray()) {
+            return new RootFutureArrayDataNode(f, dmc);
+        }
+        else if (t.isComposite()) {
+            return new RootFutureStructDataNode(f, dmc);
+        }
+        else {
+            return new RootFutureMappedSingleDataNode(f, dmc);
+        }
+    }
+    
+    public static AbstractDataNode newRoot(Type type, Object value) {
+        if (type.isPrimitive()) {
+            return new RootClosedPrimitiveDataNode(Field.Factory.getImmutableField("?", type), value);
+        }
+        else {
+            throw new IllegalArgumentException();
+        }
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/RootClosedArrayDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/RootClosedArrayDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/RootClosedArrayDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,127 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import java.util.List;
+
+import k.thr.LWThread;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.DuplicateMappingChecker;
+import org.griphyn.vdl.mapping.Mapper;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+
+public class RootClosedArrayDataNode extends AbstractClosedArrayDataNode implements RootHandle {
+	private int line = -1;
+    private LWThread thread;
+    private Mapper mapper;
+    
+    public RootClosedArrayDataNode(Field field, List<?> values, DuplicateMappingChecker dmChecker) {
+    	super(field, values);
+    	if (getType().itemType().hasMappedComponents()) {
+            this.mapper = new InitMapper(dmChecker);
+        }
+    }
+
+    @Override
+    public RootHandle getRoot() {
+        return this;
+    }
+
+    @Override
+    public DSHandle getParent() {
+        return null;
+    }
+
+    @Override
+    public Path getPathFromRoot() {
+        return Path.EMPTY_PATH;
+    }
+
+    @Override
+    public void init(Mapper mapper) {
+        if (!getType().itemType().hasMappedComponents()) {
+            return;
+        }
+        if (mapper == null) {
+            initialized();
+        }
+        else {
+            this.getInitMapper().setMapper(mapper);
+            this.mapper.initialize(this);
+        }  
+    }
+    
+    @Override
+    public void mapperInitialized(Mapper mapper) {
+        synchronized(this) {
+            this.mapper = mapper;
+        }
+        initialized();
+    }
+
+    protected void initialized() {
+        if (variableTracer.isEnabled()) {
+            variableTracer.trace(thread, line, getName() + " INITIALIZED " + mapper);
+        }
+    }
+    
+    public synchronized Mapper getMapper() {
+        if (mapper instanceof InitMapper) {
+            return ((InitMapper) mapper).getMapper();
+        }
+        else {
+            return mapper;
+        }
+    }
+
+
+    @Override
+    public int getLine() {
+        return line;
+    }
+
+    @Override
+    public void setLine(int line) {
+        this.line = line;
+    }
+
+    @Override
+    public void setThread(LWThread thread) {
+        this.thread = thread;
+    }
+
+    @Override
+    public LWThread getThread() {
+        return thread;
+    }
+    
+    @Override
+    public String getName() {
+        return (String) getField().getId();
+    }
+    
+    @Override
+    protected AbstractDataNode getParentNode() {
+        return null;
+    }
+
+    @Override
+    public Mapper getActualMapper() {
+        return mapper;
+    }
+
+    @Override
+    public void closeArraySizes() {
+        // already closed
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/RootClosedMappedSingleDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/RootClosedMappedSingleDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/RootClosedMappedSingleDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,119 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import k.thr.LWThread;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.DuplicateMappingChecker;
+import org.griphyn.vdl.mapping.Mapper;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+
+public class RootClosedMappedSingleDataNode extends AbstractClosedMappedSingleDataNode implements RootHandle {
+	private int line = -1;
+    private LWThread thread;
+    private Mapper mapper;
+    
+    public RootClosedMappedSingleDataNode(Field field, Object value, DuplicateMappingChecker dmc) {
+    	super(field, value);
+    	this.mapper = new InitMapper(dmc);
+    }
+
+        @Override
+    public RootHandle getRoot() {
+        return this;
+    }
+
+    @Override
+    public DSHandle getParent() {
+        return null;
+    }
+    
+    @Override
+    public Path getPathFromRoot() {
+        return Path.EMPTY_PATH;
+    }
+
+    @Override
+    public void init(Mapper mapper) {
+        if (mapper == null) {
+            initialized();
+        }
+        else {
+            this.getInitMapper().setMapper(mapper);
+            this.mapper.initialize(this);
+        }  
+    }
+    
+    @Override
+    public void mapperInitialized(Mapper mapper) {
+        synchronized(this) {
+            this.mapper = mapper;
+        }
+        initialized();
+    }
+
+    protected void initialized() {
+        if (variableTracer.isEnabled()) {
+            variableTracer.trace(thread, line, getName() + " INITIALIZED " + mapper);
+        }
+    }
+    
+    public synchronized Mapper getMapper() {
+        if (mapper instanceof InitMapper) {
+            return ((InitMapper) mapper).getMapper();
+        }
+        else {
+            return mapper;
+        }
+    }
+
+    @Override
+    public int getLine() {
+        return line;
+    }
+
+    @Override
+    public void setLine(int line) {
+        this.line = line;
+    }
+
+    @Override
+    public void setThread(LWThread thread) {
+        this.thread = thread;
+    }
+
+    @Override
+    public LWThread getThread() {
+        return thread;
+    }
+    
+    @Override
+    public String getName() {
+        return (String) getField().getId();
+    }
+    
+    @Override
+    protected AbstractDataNode getParentNode() {
+        return null;
+    }
+
+    @Override
+    public Mapper getActualMapper() {
+        return mapper;
+    }
+    
+    @Override
+    public void closeArraySizes() {
+        // does not apply
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/RootClosedPrimitiveDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/RootClosedPrimitiveDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/RootClosedPrimitiveDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,108 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import k.thr.LWThread;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.DependentException;
+import org.griphyn.vdl.mapping.Mapper;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+
+public class RootClosedPrimitiveDataNode extends AbstractClosedPrimitiveDataNode implements RootHandle {
+	private int line = -1;
+    private LWThread thread;
+    
+    public RootClosedPrimitiveDataNode(Field field, Object value) {
+    	super(field, value);
+    }
+    
+    public RootClosedPrimitiveDataNode(Field field, DependentException e) {
+        super(field, e);
+    }
+
+    @Override
+    public RootHandle getRoot() {
+        return this;
+    }
+
+    @Override
+    public DSHandle getParent() {
+        return null;
+    }
+    
+    @Override
+    public Path getPathFromRoot() {
+        return Path.EMPTY_PATH;
+    }
+
+    @Override
+    public void init(Mapper mapper) {
+    }
+
+    @Override
+    public void mapperInitialized(Mapper mapper) {
+    }
+
+    @Override
+    public int getLine() {
+        return line;
+    }
+
+    @Override
+    public void setLine(int line) {
+        this.line = line;
+    }
+
+    @Override
+    public boolean isInput() {
+        // maybe not strictly true, but the only place where this matters
+        // is when mapping input data, and there is no mapping for this
+        // node
+        return false;
+    }
+
+    @Override
+    public void setInput(boolean input) {
+        // noop
+    }
+
+    @Override
+    public void setThread(LWThread thread) {
+        this.thread = thread;
+    }
+
+    @Override
+    public LWThread getThread() {
+        return thread;
+    }
+    
+    @Override
+    public String getName() {
+        return (String) getField().getId();
+    }
+    
+    @Override
+    protected AbstractDataNode getParentNode() {
+        return null;
+    }
+
+    @Override
+    public Mapper getActualMapper() {
+        return null;
+    }
+    
+    @Override
+    public void closeArraySizes() {
+        // does not apply
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/RootFutureArrayDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/RootFutureArrayDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/RootFutureArrayDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,123 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import k.thr.LWThread;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.DuplicateMappingChecker;
+import org.griphyn.vdl.mapping.Mapper;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+
+public class RootFutureArrayDataNode extends AbstractFutureArrayDataNode implements RootHandle {
+	private int line = -1;
+    private LWThread thread;
+    private Mapper mapper;
+    
+    public RootFutureArrayDataNode(Field field, DuplicateMappingChecker dmc) {
+    	super(field);
+    	this.mapper = new InitMapper(dmc);
+    }
+
+    @Override
+    public RootHandle getRoot() {
+        return this;
+    }
+
+    @Override
+    public DSHandle getParent() {
+        return null;
+    }
+    
+    @Override
+    public Path getPathFromRoot() {
+        return Path.EMPTY_PATH;
+    }
+
+    @Override
+    public void init(Mapper mapper) {
+        if (!getType().itemType().hasMappedComponents()) {
+            return;
+        }
+        if (mapper == null) {
+            initialized();
+        }
+        else {
+            this.getInitMapper().setMapper(mapper);
+            this.mapper.initialize(this);
+        }  
+    }
+    
+    @Override
+    public void mapperInitialized(Mapper mapper) {
+        synchronized(this) {
+            this.mapper = mapper;
+        }
+        initialized();
+    }
+
+    protected void initialized() {
+        if (variableTracer.isEnabled()) {
+            variableTracer.trace(thread, line, getName() + " INITIALIZED " + mapper);
+        }
+    }
+    
+    public synchronized Mapper getMapper() {
+        if (mapper instanceof InitMapper) {
+            return ((InitMapper) mapper).getMapper();
+        }
+        else {
+            return mapper;
+        }
+    }
+
+
+    @Override
+    public int getLine() {
+        return line;
+    }
+
+    @Override
+    public void setLine(int line) {
+        this.line = line;
+    }
+
+    @Override
+    public void setThread(LWThread thread) {
+        this.thread = thread;
+    }
+
+    @Override
+    public LWThread getThread() {
+        return thread;
+    }
+    
+    @Override
+    public String getName() {
+        return (String) getField().getId();
+    }
+    
+    @Override
+    protected AbstractDataNode getParentNode() {
+        return null;
+    }
+
+    @Override
+    public Mapper getActualMapper() {
+        return mapper;
+    }
+    
+    @Override
+    public void closeArraySizes() {
+        closeShallow();
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/RootFutureMappedSingleDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/RootFutureMappedSingleDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/RootFutureMappedSingleDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,126 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import k.thr.LWThread;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.DuplicateMappingChecker;
+import org.griphyn.vdl.mapping.Mapper;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+
+public class RootFutureMappedSingleDataNode extends AbstractFutureMappedSingleDataNode implements RootHandle {
+	private int line = -1;
+    
+    private LWThread thread;
+    
+    private Mapper mapper;
+    
+    public RootFutureMappedSingleDataNode(Field field, DuplicateMappingChecker dmc) {
+    	super(field);
+    	if (field == null) {
+    	    throw new NullPointerException();
+    	}
+    	this.mapper = new InitMapper(dmc);
+    }
+
+    @Override
+    public RootHandle getRoot() {
+        return this;
+    }
+
+    @Override
+    public DSHandle getParent() {
+        return null;
+    }
+    
+    @Override
+    public Path getPathFromRoot() {
+        return Path.EMPTY_PATH;
+    }
+
+    
+    @Override
+    public void init(Mapper mapper) {
+        if (mapper == null) {
+            initialized();
+        }
+        else {
+            this.getInitMapper().setMapper(mapper);
+            this.mapper.initialize(this);
+        }  
+    }
+    
+    @Override
+    public void mapperInitialized(Mapper mapper) {
+        synchronized(this) {
+            this.mapper = mapper;
+        }
+        initialized();
+    }
+
+    protected void initialized() {
+        if (variableTracer.isEnabled()) {
+            variableTracer.trace(thread, line, getName() + " INITIALIZED " + mapper);
+        }
+    }
+    
+    public synchronized Mapper getMapper() {
+        if (mapper instanceof InitMapper) {
+            return ((InitMapper) mapper).getMapper();
+        }
+        else {
+            return mapper;
+        }
+    }
+
+
+    @Override
+    public int getLine() {
+        return line;
+    }
+
+    @Override
+    public void setLine(int line) {
+        this.line = line;
+    }
+
+    @Override
+    public void setThread(LWThread thread) {
+        this.thread = thread;
+    }
+
+    @Override
+    public LWThread getThread() {
+        return thread;
+    }
+    
+    @Override
+    public String getName() {
+        return (String) getField().getId();
+    }
+    
+    @Override
+    protected AbstractDataNode getParentNode() {
+        return null;
+    }
+
+    @Override
+    public Mapper getActualMapper() {
+        return mapper;
+    }
+    
+    @Override
+    public void closeArraySizes() {
+        // does not apply
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/RootFuturePrimitiveDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/RootFuturePrimitiveDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/RootFuturePrimitiveDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,100 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import k.thr.LWThread;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.Mapper;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+
+public class RootFuturePrimitiveDataNode extends AbstractFuturePrimitiveDataNode implements RootHandle {
+	private int line = -1;
+    private LWThread thread;
+    
+    public RootFuturePrimitiveDataNode(Field field) {
+    	super(field);
+    }
+
+    @Override
+    public RootHandle getRoot() {
+        return this;
+    }
+
+    @Override
+    public DSHandle getParent() {
+        return null;
+    }
+    
+    @Override
+    public Path getPathFromRoot() {
+        return Path.EMPTY_PATH;
+    }
+
+    @Override
+    public void init(Mapper mapper) {
+    }
+
+    @Override
+    public void mapperInitialized(Mapper mapper) {
+    }
+
+    @Override
+    public int getLine() {
+        return line;
+    }
+
+    @Override
+    public void setLine(int line) {
+        this.line = line;
+    }
+
+    @Override
+    public boolean isInput() {
+        return false;
+    }
+
+    @Override
+    public void setInput(boolean input) {
+        // doesn't matter
+    }
+
+    @Override
+    public void setThread(LWThread thread) {
+        this.thread = thread;
+    }
+
+    @Override
+    public LWThread getThread() {
+        return thread;
+    }
+    
+    @Override
+    public String getName() {
+        return (String) getField().getId();
+    }
+    
+    @Override
+    protected AbstractDataNode getParentNode() {
+        return null;
+    }
+
+    @Override
+    public Mapper getActualMapper() {
+        return null;
+    }
+    
+    @Override
+    public void closeArraySizes() {
+        // does not apply
+    }
+}

Added: trunk/src/org/griphyn/vdl/mapping/nodes/RootFutureStructDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/nodes/RootFutureStructDataNode.java	                        (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/nodes/RootFutureStructDataNode.java	2014-05-09 04:35:05 UTC (rev 7839)
@@ -0,0 +1,137 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Mar 28, 2014
+ */
+package org.griphyn.vdl.mapping.nodes;
+
+import k.thr.LWThread;
+
+import org.griphyn.vdl.mapping.DSHandle;
+import org.griphyn.vdl.mapping.DuplicateMappingChecker;
+import org.griphyn.vdl.mapping.Mapper;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.RootHandle;
+import org.griphyn.vdl.type.Field;
+
+public class RootFutureStructDataNode extends AbstractFutureStructDataNode implements RootHandle {
+	private int line = -1;
+    private LWThread thread;
+    private boolean input;
+    private Mapper mapper;
+    
+    public RootFutureStructDataNode(Field field, DuplicateMappingChecker dmc) {
+    	super(field, null);
+    	if (getType().itemType().hasMappedComponents()) {
+            this.mapper = new InitMapper(dmc);
+        }
+    }
+
+    @Override
+    public RootHandle getRoot() {
+        return this;
+    }
+
+    @Override
+    public DSHandle getParent() {
+        return null;
+    }
+    
+    @Override
+    public Path getPathFromRoot() {
+        return Path.EMPTY_PATH;
+    }
+
+    @Override
+    public void init(Mapper mapper) {
+        initialize();
+        if (!getType().itemType().hasMappedComponents()) {
+            return;
+        }
+        if (mapper == null) {
+            initialized();
+        }
+        else {
+            this.getInitMapper().setMapper(mapper);
+            this.mapper.initialize(this);
+        }  
+    }
+    
+    @Override
+    public void mapperInitialized(Mapper mapper) {
+        synchronized(this) {
+            this.mapper = mapper;
+        }
+        initialized();
+    }
+
+    protected void initialized() {
+        if (variableTracer.isEnabled()) {
+            variableTracer.trace(thread, line, getName() + " INITIALIZED " + mapper);
+        }
+    }
+    
+    public synchronized Mapper getMapper() {
+        if (mapper instanceof InitMapper) {
+            return ((InitMapper) mapper).getMapper();
+        }
+        else {
+            return mapper;
+        }
+    }
+
+
+    @Override
+    public int getLine() {
+        return line;
+    }
+
+    @Override
+    public void setLine(int line) {
+        this.line = line;
+    }
+
+    @Override
+    public boolean isInput() {
+        return input;
+    }
+
+    @Override
+    public void setInput(boolean input) {
+        this.input = input;
+    }
+
+    @Override
+    public void setThread(LWThread thread) {
+        this.thread = thread;
+    }
+
+    @Override
+    public LWThread getThread() {
+        return thread;
+    }
+    
+    @Override
+    public String getName() {
+        return (String) getField().getId();
+    }
+    
+    @Override
+    protected AbstractDataNode getParentNode() {
+        return null;
+    }
+
+    @Override
+    public Mapper getActualMapper() {
+        return mapper;
+    }
+    
+    @Override
+    public void closeArraySizes() {
+        // does not apply
+    }
+}




More information about the Swift-commit mailing list