Refactored the OpenFlow controller package name-space and fixed a number of Javadoc warnings.
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/debugcounter/DebugCounter.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/debugcounter/DebugCounter.java
new file mode 100644
index 0000000..f88a43e
--- /dev/null
+++ b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/debugcounter/DebugCounter.java
@@ -0,0 +1,727 @@
+package org.onlab.onos.of.controller.impl.debugcounter;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+import com.google.common.collect.Sets;
+
+
+
+/**
+ * This class implements a central store for all counters used for debugging the
+ * system. For counters based on traffic-type, see ICounterStoreService.
+ *
+ */
+//CHECKSTYLE:OFF
+public class DebugCounter implements IDebugCounterService {
+    protected static final Logger log = LoggerFactory.getLogger(DebugCounter.class);
+
+    /**
+     * registered counters need a counter id.
+     */
+    protected AtomicInteger counterIdCounter = new AtomicInteger();
+
+    /**
+     * The counter value.
+     */
+    protected static class MutableLong {
+        long value = 0;
+        public void increment() { value += 1; }
+        public void increment(long incr) { value += incr; }
+        public long get() { return value; }
+        public void set(long val) { value = val; }
+      }
+
+    /**
+     * protected class to store counter information.
+     */
+    public static class CounterInfo {
+        String moduleCounterHierarchy;
+        String counterDesc;
+        CounterType ctype;
+        String moduleName;
+        String counterHierarchy;
+        int counterId;
+        boolean enabled;
+        String[] metaData;
+
+        public CounterInfo(int counterId, boolean enabled,
+                           String moduleName, String counterHierarchy,
+                           String desc, CounterType ctype, String... metaData) {
+            this.moduleCounterHierarchy = moduleName + "/" + counterHierarchy;
+            this.moduleName = moduleName;
+            this.counterHierarchy = counterHierarchy;
+            this.counterDesc = desc;
+            this.ctype = ctype;
+            this.counterId = counterId;
+            this.enabled = enabled;
+            this.metaData = metaData;
+        }
+
+        public String getModuleCounterHierarchy() { return moduleCounterHierarchy; }
+        public String getCounterDesc() { return counterDesc; }
+        public CounterType getCtype() { return ctype; }
+        public String getModuleName() { return moduleName; }
+        public String getCounterHierarchy() { return counterHierarchy; }
+        public int getCounterId() { return counterId; }
+        public boolean isEnabled() { return enabled; }
+        public String[] getMetaData() { return this.metaData.clone(); }
+    }
+
+    //******************
+    //   Global stores
+    //******************
+
+    /**
+     * Counter info for a debug counter.
+     */
+    public static class DebugCounterInfo {
+        CounterInfo cinfo;
+        AtomicLong cvalue;
+
+        public DebugCounterInfo(CounterInfo cinfo) {
+            this.cinfo = cinfo;
+            this.cvalue = new AtomicLong();
+        }
+        public CounterInfo getCounterInfo() {
+            return cinfo;
+        }
+        public Long getCounterValue() {
+            return cvalue.get();
+        }
+    }
+
+    /**
+     * Global debug-counter storage across all threads. These are
+     * updated from the local per thread counters by the flush counters method.
+     */
+    private static final DebugCounterInfo[] ALLCOUNTERS =
+                            new DebugCounterInfo[MAX_COUNTERS];
+
+
+    /**
+     * per module counters, indexed by the module name and storing three levels
+     * of Counter information in the form of CounterIndexStore.
+     */
+    protected ConcurrentHashMap<String, ConcurrentHashMap<String, CounterIndexStore>>
+        moduleCounters = new ConcurrentHashMap<String,
+                                                ConcurrentHashMap<String,
+                                                                   CounterIndexStore>>();
+
+    protected static class CounterIndexStore {
+        int index;
+        Map<String, CounterIndexStore> nextLevel;
+
+        public CounterIndexStore(int index, Map<String, CounterIndexStore> cis) {
+            this.index = index;
+            this.nextLevel = cis;
+        }
+    }
+
+    /**
+     * fast global cache for counter ids that are currently active.
+     */
+    protected Set<Integer> currentCounters = Collections.newSetFromMap(
+                                         new ConcurrentHashMap<Integer, Boolean>());
+
+    //******************
+    // Thread local stores
+    //******************
+
+    /**
+     * Thread local storage of counter info.
+     */
+    protected static class LocalCounterInfo {
+        boolean enabled;
+        MutableLong cvalue;
+
+        public LocalCounterInfo(boolean enabled) {
+            this.enabled = enabled;
+            this.cvalue = new MutableLong();
+        }
+    }
+
+    /**
+     * Thread local debug counters used for maintaining counters local to a thread.
+     */
+    protected final ThreadLocal<LocalCounterInfo[]> threadlocalCounters =
+            new ThreadLocal<LocalCounterInfo[]>() {
+        @Override
+        protected LocalCounterInfo[] initialValue() {
+            return new LocalCounterInfo[MAX_COUNTERS];
+        }
+    };
+
+    /**
+     * Thread local cache for counter ids that are currently active.
+     */
+    protected final ThreadLocal<Set<Integer>> threadlocalCurrentCounters =
+            new ThreadLocal<Set<Integer>>() {
+        @Override
+        protected Set<Integer> initialValue() {
+            return new HashSet<Integer>();
+        }
+    };
+
+    //*******************************
+    //   IDebugCounter
+    //*******************************
+
+    protected class CounterImpl implements IDebugCounter {
+        private final int counterId;
+
+        public CounterImpl(int counterId) {
+            this.counterId = counterId;
+        }
+
+        @Override
+        public void updateCounterWithFlush() {
+            if (!validCounterId()) {
+                return;
+            }
+            updateCounter(counterId, 1, true);
+        }
+
+        @Override
+        public void updateCounterNoFlush() {
+            if (!validCounterId()) {
+                return;
+            }
+            updateCounter(counterId, 1, false);
+        }
+
+        @Override
+        public void updateCounterWithFlush(int incr) {
+            if (!validCounterId()) {
+                return;
+            }
+            updateCounter(counterId, incr, true);
+        }
+
+        @Override
+        public void updateCounterNoFlush(int incr) {
+            if (!validCounterId()) {
+                return;
+            }
+            updateCounter(counterId, incr, false);
+        }
+
+        @Override
+        public long getCounterValue() {
+            if (!validCounterId()) {
+                return -1;
+            }
+            return ALLCOUNTERS[counterId].cvalue.get();
+        }
+
+        /**
+         * Checks if this is a valid counter.
+         * @return true if the counter id is valid
+         */
+        private boolean validCounterId() {
+            if (counterId < 0 || counterId >= MAX_COUNTERS) {
+                log.error("Invalid counterId invoked");
+                return false;
+            }
+            return true;
+        }
+
+    }
+
+   //*******************************
+   //   IDebugCounterService
+   //*******************************
+
+   @Override
+   public IDebugCounter registerCounter(String moduleName, String counterHierarchy,
+                           String counterDescription, CounterType counterType,
+                           String... metaData)
+               throws CounterException {
+       // check if counter already exists
+       if (!moduleCounters.containsKey(moduleName)) {
+           moduleCounters.putIfAbsent(moduleName,
+                new ConcurrentHashMap<String, CounterIndexStore>());
+       }
+       RetCtrInfo rci = getCounterId(moduleName, counterHierarchy);
+       if (rci.allLevelsFound) {
+           // counter exists
+           log.info("Counter exists for {}/{} -- resetting counters", moduleName,
+                    counterHierarchy);
+           resetCounterHierarchy(moduleName, counterHierarchy);
+           return new CounterImpl(rci.ctrIds[rci.foundUptoLevel - 1]);
+       }
+       // check for validity of counter
+       if (rci.levels.length > MAX_HIERARCHY) {
+           String err = "Registry of counterHierarchy " + counterHierarchy +
+                   " exceeds max hierachy " + MAX_HIERARCHY + ".. aborting";
+           throw new MaxHierarchyRegistered(err);
+       }
+       if (rci.foundUptoLevel < rci.levels.length - 1) {
+           StringBuilder sb = new StringBuilder();
+           for (int i = 0; i <= rci.foundUptoLevel; i++) {
+               sb.append(rci.levels[i]);
+           }
+           String needToRegister = sb.toString();
+           String err = "Attempting to register hierarchical counterHierarchy " +
+                   counterHierarchy + " but parts of hierarchy missing. " +
+                   "Please register " +  needToRegister + " first";
+           throw new MissingHierarchicalLevel(err);
+       }
+
+       // get a new counter id
+       int counterId = counterIdCounter.getAndIncrement();
+       if (counterId >= MAX_COUNTERS) {
+           throw new MaxCountersRegistered("max counters reached");
+       }
+       // create storage for counter
+       boolean enabled = (counterType == CounterType.ALWAYS_COUNT) ? true : false;
+       CounterInfo ci = new CounterInfo(counterId, enabled, moduleName,
+                                        counterHierarchy, counterDescription,
+                                        counterType, metaData);
+       ALLCOUNTERS[counterId] = new DebugCounterInfo(ci);
+
+       // account for the new counter in the module counter hierarchy
+       addToModuleCounterHierarchy(moduleName, counterId, rci);
+
+       // finally add to active counters
+       if (enabled) {
+           currentCounters.add(counterId);
+       }
+       return new CounterImpl(counterId);
+   }
+
+   private void updateCounter(int counterId, int incr, boolean flushNow) {
+       if (counterId < 0 || counterId >= MAX_COUNTERS) {
+        return;
+    }
+
+       LocalCounterInfo[] thiscounters =  this.threadlocalCounters.get();
+       if (thiscounters[counterId] == null) {
+           // seeing this counter for the first time in this thread - create local
+           // store by consulting global store
+           DebugCounterInfo dc = ALLCOUNTERS[counterId];
+           if (dc != null) {
+               thiscounters[counterId] = new LocalCounterInfo(dc.cinfo.enabled);
+               if (dc.cinfo.enabled) {
+                   Set<Integer> thisset = this.threadlocalCurrentCounters.get();
+                   thisset.add(counterId);
+               }
+           } else {
+               log.error("updateCounter seen locally for counter {} but no global"
+                          + "storage exists for it yet .. not updating", counterId);
+               return;
+           }
+       }
+
+       // update local store if enabled locally for updating
+       LocalCounterInfo lc = thiscounters[counterId];
+       if (lc.enabled) {
+           lc.cvalue.increment(incr);
+           if (flushNow) {
+               DebugCounterInfo dc = ALLCOUNTERS[counterId];
+               if (dc.cinfo.enabled) {
+                   // globally enabled - flush now
+                   dc.cvalue.addAndGet(lc.cvalue.get());
+                   lc.cvalue.set(0);
+               } else {
+                   // global counter is disabled - don't flush, disable locally
+                   lc.enabled = false;
+                   Set<Integer> thisset = this.threadlocalCurrentCounters.get();
+                   thisset.remove(counterId);
+               }
+           }
+       }
+   }
+
+   @Override
+   public void flushCounters() {
+       LocalCounterInfo[] thiscounters =  this.threadlocalCounters.get();
+       Set<Integer> thisset = this.threadlocalCurrentCounters.get();
+       ArrayList<Integer> temp = new ArrayList<Integer>();
+
+       for (int counterId : thisset) {
+           LocalCounterInfo lc = thiscounters[counterId];
+           if (lc.cvalue.get() > 0) {
+               DebugCounterInfo dc = ALLCOUNTERS[counterId];
+               if (dc.cinfo.enabled) {
+                   // globally enabled - flush now
+                   dc.cvalue.addAndGet(lc.cvalue.get());
+                   lc.cvalue.set(0);
+               } else {
+                   // global counter is disabled - don't flush, disable locally
+                   lc.enabled = false;
+                   temp.add(counterId);
+               }
+           }
+       }
+       for (int cId : temp) {
+           thisset.remove(cId);
+       }
+
+       // At this point it is possible that the thread-local set does not
+       // include a counter that has been enabled and is present in the global set.
+       // We need to sync thread-local currently enabled set of counterIds with
+       // the global set.
+       Sets.SetView<Integer> sv = Sets.difference(currentCounters, thisset);
+       for (int counterId : sv) {
+           if (thiscounters[counterId] != null) {
+               thiscounters[counterId].enabled = true;
+               thisset.add(counterId);
+           }
+       }
+   }
+
+   @Override
+   public void resetCounterHierarchy(String moduleName, String counterHierarchy) {
+       RetCtrInfo rci = getCounterId(moduleName, counterHierarchy);
+       if (!rci.allLevelsFound) {
+           String missing = rci.levels[rci.foundUptoLevel];
+           log.error("Cannot reset counter hierarchy - missing counter {}", missing);
+           return;
+       }
+       // reset at this level
+       ALLCOUNTERS[rci.ctrIds[rci.foundUptoLevel - 1]].cvalue.set(0);
+       // reset all levels below
+       ArrayList<Integer> resetIds = getHierarchyBelow(moduleName, rci);
+       for (int index : resetIds) {
+           ALLCOUNTERS[index].cvalue.set(0);
+       }
+   }
+
+   @Override
+   public void resetAllCounters() {
+       RetCtrInfo rci = new RetCtrInfo();
+       rci.levels = "".split("/");
+       for (String moduleName : moduleCounters.keySet()) {
+           ArrayList<Integer> resetIds = getHierarchyBelow(moduleName, rci);
+           for (int index : resetIds) {
+               ALLCOUNTERS[index].cvalue.set(0);
+           }
+       }
+   }
+
+   @Override
+   public void resetAllModuleCounters(String moduleName) {
+       Map<String, CounterIndexStore> target = moduleCounters.get(moduleName);
+       RetCtrInfo rci = new RetCtrInfo();
+       rci.levels = "".split("/");
+
+       if (target != null) {
+           ArrayList<Integer> resetIds = getHierarchyBelow(moduleName, rci);
+           for (int index : resetIds) {
+               ALLCOUNTERS[index].cvalue.set(0);
+           }
+       } else {
+           if (log.isDebugEnabled()) {
+            log.debug("No module found with name {}", moduleName);
+        }
+       }
+   }
+
+   @Override
+   public void enableCtrOnDemand(String moduleName, String counterHierarchy) {
+       RetCtrInfo rci = getCounterId(moduleName, counterHierarchy);
+       if (!rci.allLevelsFound) {
+           String missing = rci.levels[rci.foundUptoLevel];
+           log.error("Cannot enable counter - counter not found {}", missing);
+           return;
+       }
+       // enable specific counter
+       DebugCounterInfo dc = ALLCOUNTERS[rci.ctrIds[rci.foundUptoLevel - 1]];
+       dc.cinfo.enabled = true;
+       currentCounters.add(dc.cinfo.counterId);
+   }
+
+   @Override
+   public void disableCtrOnDemand(String moduleName, String counterHierarchy) {
+       RetCtrInfo rci = getCounterId(moduleName, counterHierarchy);
+       if (!rci.allLevelsFound) {
+           String missing = rci.levels[rci.foundUptoLevel];
+           log.error("Cannot disable counter - counter not found {}", missing);
+           return;
+       }
+       // disable specific counter
+       DebugCounterInfo dc = ALLCOUNTERS[rci.ctrIds[rci.foundUptoLevel - 1]];
+       if (dc.cinfo.ctype == CounterType.COUNT_ON_DEMAND) {
+           dc.cinfo.enabled = false;
+           dc.cvalue.set(0);
+           currentCounters.remove(dc.cinfo.counterId);
+       }
+   }
+
+   @Override
+   public List<DebugCounterInfo> getCounterHierarchy(String moduleName,
+                                                     String counterHierarchy) {
+       RetCtrInfo rci = getCounterId(moduleName, counterHierarchy);
+       if (!rci.allLevelsFound) {
+           String missing = rci.levels[rci.foundUptoLevel];
+           log.error("Cannot fetch counter - counter not found {}", missing);
+           return Collections.emptyList();
+       }
+       ArrayList<DebugCounterInfo> dcilist = new ArrayList<DebugCounterInfo>();
+       // get counter and all below it
+       DebugCounterInfo dc = ALLCOUNTERS[rci.ctrIds[rci.foundUptoLevel - 1]];
+       dcilist.add(dc);
+       ArrayList<Integer> belowIds = getHierarchyBelow(moduleName, rci);
+       for (int index : belowIds) {
+           dcilist.add(ALLCOUNTERS[index]);
+       }
+       return dcilist;
+   }
+
+   @Override
+   public List<DebugCounterInfo> getAllCounterValues() {
+       List<DebugCounterInfo> dcilist = new ArrayList<DebugCounterInfo>();
+       RetCtrInfo rci = new RetCtrInfo();
+       rci.levels = "".split("/");
+
+       for (String moduleName : moduleCounters.keySet()) {
+           ArrayList<Integer> resetIds = getHierarchyBelow(moduleName, rci);
+           for (int index : resetIds) {
+               dcilist.add(ALLCOUNTERS[index]);
+           }
+       }
+       return dcilist;
+   }
+
+   @Override
+   public List<DebugCounterInfo> getModuleCounterValues(String moduleName) {
+       List<DebugCounterInfo> dcilist = new ArrayList<DebugCounterInfo>();
+       RetCtrInfo rci = new RetCtrInfo();
+       rci.levels = "".split("/");
+
+       if (moduleCounters.containsKey(moduleName)) {
+           ArrayList<Integer> resetIds = getHierarchyBelow(moduleName, rci);
+           for (int index : resetIds) {
+               dcilist.add(ALLCOUNTERS[index]);
+           }
+       }
+       return dcilist;
+   }
+
+   @Override
+   public boolean containsModuleCounterHierarchy(String moduleName,
+                                                 String counterHierarchy) {
+       if (!moduleCounters.containsKey(moduleName)) {
+        return false;
+    }
+       RetCtrInfo rci = getCounterId(moduleName, counterHierarchy);
+       return rci.allLevelsFound;
+   }
+
+   @Override
+   public boolean containsModuleName(String moduleName) {
+       return  (moduleCounters.containsKey(moduleName)) ? true : false;
+   }
+
+   @Override
+   public List<String> getModuleList() {
+       List<String> retval = new ArrayList<String>();
+       retval.addAll(moduleCounters.keySet());
+       return retval;
+   }
+
+   @Override
+   public List<String> getModuleCounterList(String moduleName) {
+       if (!moduleCounters.containsKey(moduleName)) {
+        return Collections.emptyList();
+    }
+
+       List<String> retval = new ArrayList<String>();
+       RetCtrInfo rci = new RetCtrInfo();
+       rci.levels = "".split("/");
+
+       ArrayList<Integer> cids = getHierarchyBelow(moduleName, rci);
+       for (int index : cids) {
+           retval.add(ALLCOUNTERS[index].cinfo.counterHierarchy);
+       }
+       return retval;
+   }
+
+   //*******************************
+   //   Internal Methods
+   //*******************************
+
+   protected class RetCtrInfo {
+       boolean allLevelsFound; // counter indices found all the way down the hierarchy
+       boolean hierarchical; // true if counterHierarchy is hierarchical
+       int foundUptoLevel;
+       int[]  ctrIds;
+       String[] levels;
+
+       public RetCtrInfo() {
+           ctrIds = new int[MAX_HIERARCHY];
+           for (int i = 0; i < MAX_HIERARCHY; i++) {
+               ctrIds[i] = -1;
+           }
+       }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + getOuterType().hashCode();
+        result = prime * result + (allLevelsFound ? 1231 : 1237);
+        result = prime * result + Arrays.hashCode(ctrIds);
+        result = prime * result + foundUptoLevel;
+        result = prime * result + (hierarchical ? 1231 : 1237);
+        result = prime * result + Arrays.hashCode(levels);
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object oth) {
+        if (!(oth instanceof RetCtrInfo)) {
+         return false;
+     }
+        RetCtrInfo other = (RetCtrInfo) oth;
+        if (other.allLevelsFound != this.allLevelsFound) {
+         return false;
+     }
+        if (other.hierarchical != this.hierarchical) {
+         return false;
+     }
+        if (other.foundUptoLevel != this.foundUptoLevel) {
+         return false;
+     }
+        if (!Arrays.equals(other.ctrIds, this.ctrIds)) {
+         return false;
+     }
+        if (!Arrays.equals(other.levels, this.levels)) {
+         return false;
+     }
+        return true;
+    }
+
+    private DebugCounter getOuterType() {
+        return DebugCounter.this;
+    }
+
+
+
+   }
+
+   protected RetCtrInfo getCounterId(String moduleName, String counterHierarchy) {
+       RetCtrInfo rci = new RetCtrInfo();
+       Map<String, CounterIndexStore> templevel = moduleCounters.get(moduleName);
+       rci.levels = counterHierarchy.split("/");
+       if (rci.levels.length > 1) {
+        rci.hierarchical = true;
+    }
+       if (templevel == null) {
+           log.error("moduleName {} does not exist in debugCounters", moduleName);
+           return rci;
+       }
+
+       /*
+       if (rci.levels.length > MAX_HIERARCHY) {
+           // chop off all array elems greater that MAX_HIERARCHY
+           String[] temp = new String[MAX_HIERARCHY];
+           System.arraycopy(rci.levels, 0, temp, 0, MAX_HIERARCHY);
+           rci.levels = temp;
+       }
+       */
+       for (int i = 0; i < rci.levels.length; i++) {
+           if (templevel != null) {
+               CounterIndexStore cis = templevel.get(rci.levels[i]);
+               if (cis == null) {
+                   // could not find counterHierarchy part at this level
+                   break;
+               } else {
+                   rci.ctrIds[i] = cis.index;
+                   templevel = cis.nextLevel;
+                   rci.foundUptoLevel++;
+                   if (i == rci.levels.length - 1) {
+                       rci.allLevelsFound = true;
+                   }
+               }
+           } else {
+               // there are no more levels, which means that some part of the
+               // counterHierarchy has no corresponding map
+               break;
+           }
+       }
+       return rci;
+   }
+
+   protected void addToModuleCounterHierarchy(String moduleName, int counterId,
+                                            RetCtrInfo rci) {
+       Map<String, CounterIndexStore> target = moduleCounters.get(moduleName);
+       if (target == null) {
+        return;
+    }
+       CounterIndexStore cis = null;
+
+       for (int i = 0; i < rci.foundUptoLevel; i++) {
+           cis = target.get(rci.levels[i]);
+           target = cis.nextLevel;
+       }
+       if (cis != null) {
+           if (cis.nextLevel == null) {
+            cis.nextLevel = new ConcurrentHashMap<String, CounterIndexStore>();
+        }
+           cis.nextLevel.put(rci.levels[rci.foundUptoLevel],
+                             new CounterIndexStore(counterId, null));
+       } else {
+           target.put(rci.levels[rci.foundUptoLevel],
+                      new CounterIndexStore(counterId, null));
+       }
+   }
+
+   // given a partial hierarchical counter, return the rest of the hierarchy
+   protected ArrayList<Integer> getHierarchyBelow(String moduleName, RetCtrInfo rci) {
+       Map<String, CounterIndexStore> target = moduleCounters.get(moduleName);
+       CounterIndexStore cis = null;
+       ArrayList<Integer> retval = new ArrayList<Integer>();
+       if (target == null) {
+        return retval;
+    }
+
+       // get to the level given
+       for (int i = 0; i < rci.foundUptoLevel; i++) {
+           cis = target.get(rci.levels[i]);
+           target = cis.nextLevel;
+       }
+
+       if (target == null || rci.foundUptoLevel == MAX_HIERARCHY) {
+           // no more levels
+           return retval;
+       } else {
+           // recursively get all ids
+           getIdsAtLevel(target, retval, rci.foundUptoLevel + 1);
+       }
+
+       return retval;
+   }
+
+   protected void getIdsAtLevel(Map<String, CounterIndexStore> hcy,
+                                ArrayList<Integer> retval, int level) {
+       if (level > MAX_HIERARCHY) {
+        return;
+    }
+       if (hcy == null || retval == null) {
+        return;
+    }
+
+       // Can return the counter names as well but for now ids are enough.
+       for (CounterIndexStore cistemp : hcy.values()) {
+           retval.add(cistemp.index); // value at this level
+           if (cistemp.nextLevel != null) {
+               getIdsAtLevel(cistemp.nextLevel, retval, level + 1);
+           }
+       }
+   }
+
+}