gt: 		if (dimension>=dimensionNames.size())     return null;
context: /*-
   *******************************************************************************
   * Copyright (c) 2011, 2016 Diamond Light Source Ltd.
   * All rights reserved. This program and the accompanying materials
   * are made available under the terms of the Eclipse Public License v1.0
   * which accompanies this distribution, and is available at
   * http://www.eclipse.org/legal/epl-v10.html
   *
   * Contributors:
   *    Matthew Gerring - initial API and implementation and/or initial documentation
   *******************************************************************************/
  package org.eclipse.scanning.api.points;
  
  import java.io.Serializable;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.Collections;
  import java.util.Iterator;
  import java.util.LinkedHashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.stream.Collectors;
  
  public abstract class AbstractPosition implements IPosition, Serializable {
  
  	/**
  	 *
  	 */
  	private static final long serialVersionUID = 8555957478192358365L;
  
  	private int stepIndex = -1;
  	private double exposureTime;
  	protected List<Collection<String>> dimensionNames; // Dimension->Names@dimension
  
  	@Override
  	public final IPosition compound(IPosition parent) {
  		if (parent==null) return this; // this+null = this
  		final MapPosition ret = new MapPosition();
  		ret.putAll(parent);
  		ret.putAll(this);
  		ret.putAllIndices(parent);
  		ret.putAllIndices(this);
  		ret.setStepIndex(getStepIndex());
  		ret.setExposureTime(getExposureTime());
  
  		List<Collection<String>> dimensionNames = new ArrayList<>();
  		dimensionNames.addAll(((AbstractPosition) parent).getDimensionNames());
  		dimensionNames.addAll(getDimensionNames());
  		ret.setDimensionNames(dimensionNames);
  
  		return ret;
  	}
  
  	@Override
  	public int hashCode() {
  		final int prime = 31;
  		int result = 1;
  		long temp;
  		final List<String> names = new ArrayList<String>(getNames());
  		Collections.sort(names);
  		for (String name : names) {
  			Object val = get(name);
  			if (val instanceof Number) {
  			    temp = Double.doubleToLongBits(((Number)val).doubleValue());
  			} else {
  				temp = val.hashCode();
  			}
  			result = prime * result + (int) (temp ^ (temp >>> 32));
  		}
    	    return result+stepIndex;
  	}
  
  	/**
  	 * Do not override equals.
  	 *
  	 * MapPostion("x:1,y:1") should equal Point("x", 1, "y",1)
  	 * because they represent the same motor values.
  	 *
  	 * @param obj
  	 * @param checkStep
  	 * @return
  	 */
  	public final boolean equals(Object obj, boolean checkStep) {
  
  		if (this == obj)
  			return true;
  
  		if (obj == null)
  			return false;
  
  		if (checkStep) {
  			if (stepIndex != ((IPosition)obj).getStepIndex())
  				return false;
  			if (exposureTime != ((IPosition)obj).getExposureTime())
  				return false;
  		}
  
  		final List<String> ours = new ArrayList<String>(getNames());
  		final List<String> theirs = new ArrayList<String>(((IPosition)obj).getNames());
  		Collections.sort(ours);
  		Collections.sort(theirs);
  		if (!equals(ours, theirs)) return false;
  		for (String name : ours) {
  			Object val1 = get(name);
  			Object val2 = ((IPosition)obj).get(name);
  			if (val1==null && val2!=null) return false;
  			if (val1!=null && val2==null) return false;
  			if (!val1.equals(val2)) return false;
  		}
  
  		final Map<String, Integer> iours   = getIndices();
  		final Map<String, Integer> itheirs = getIndices((IPosition)obj);
  		if (!iours.equals(itheirs)) return false;
  
  		List<List<String>> ourDimNames = getDimensionNames().stream()
  				.map(c -> new ArrayList<String>(c))
  				.collect(Collectors.toList());
  		ourDimNames.forEach(c -> Collections.sort(c));
  		List<List<String>> theirDimNames = getDimensionNames((IPosition) obj).stream()
  				.map(c -> new ArrayList<String>(c))
  				.collect(Collectors.toList());
  		theirDimNames.forEach(c -> Collections.sort(c));
  
  		if (!equals(ourDimNames, theirDimNames)) return false;
  
  		return true;
  	}
  
  	private Map<String, Integer> getIndices(IPosition pos) {
  		if (pos instanceof AbstractPosition) return ((AbstractPosition)pos).getIndices(); // Might be null
  		Map<String, Integer> ret = new LinkedHashMap<String, Integer>(pos.getNames().size());
  		for (String name : pos.getNames()) ret.put(name,  pos.getIndex(name));
  		return ret;
  	}
  
  	/**
  	 * This equals does an equals on two collections
  	 * as if they were two lists because order matters with the names.
  	 * @param o
  	 * @param t
  	 * @return
  	 */
      private boolean equals(Collection<?> o, Collection<?> t) {
  
      	if (o == t)
              return true;
      	if (o == null && t == null)
              return true;
      	if (o == null || t == null)
              return false;
  
          Iterator<?> e1 = o.iterator();
          Iterator<?> e2 = t.iterator();
          while (e1.hasNext() && e2.hasNext()) {
              Object o1 = e1.next();
              Object o2 = e2.next();
  
              // Collections go down to the same equals.
              if (o1 instanceof Collection && o2 instanceof Collection) {
              	boolean collectionsEqual = equals((Collection<?>)o1,(Collection<?>)o2);
              	if (!collectionsEqual) {
              		return false;
              	} else {
              		continue;
              	}
              }
  
              // Otherwise we use object equals.
              if (!(o1==null ? o2==null : o1.equals(o2)))
                  return false;
          }
          return !(e1.hasNext() || e2.hasNext());
      }
  
  	@Override
  	public boolean equals(Object obj) {
  		return equals(obj, true);
  	}
  
  	@Override
  	public String toString() {
  		StringBuilder buf = new StringBuilder("[");
  		final Collection<String> names   = getNames();
          for (Iterator<String> it = names.iterator(); it.hasNext();) {
  			String name = it.next();
          	buf.append(name);
          	int index = getIndex(name);
          	if(index>-1) {
  	        	buf.append("(");
  	        	buf.append(index);
  	        	buf.append(")");
          	}
           	buf.append("=");
          	buf.append(get(name));
          	if (it.hasNext()) buf.append(", ");
  		}
          buf.append(", step=");
          buf.append(getStepIndex());
  
          if (getExposureTime()>0) {
  	        buf.append(", exp=");
  	        buf.append(getExposureTime());
          }
  
      	buf.append("]");
      	return buf.toString();
  	}
  
  	public Collection<String> getDimensionNames(int dimension) {
  		if (dimensionNames==null && dimension==0) return getNames();
  		if (dimensionNames==null)                 return null;
  