Print

Print


Author: [log in to unmask]
Date: Wed Jul  8 14:47:40 2015
New Revision: 3252

Log:
Merge in HPSJAVA-488 branch to trunk.

Added:
    java/trunk/conditions/src/main/java/org/hps/conditions/api/AbstractConditionsObjectConverter.java
      - copied unchanged from r3250, java/branches/HPSJAVA-488/conditions/src/main/java/org/hps/conditions/api/AbstractConditionsObjectConverter.java
    java/trunk/conditions/src/main/java/org/hps/conditions/api/DatabaseObject.java
      - copied unchanged from r3250, java/branches/HPSJAVA-488/conditions/src/main/java/org/hps/conditions/api/DatabaseObject.java
    java/trunk/conditions/src/main/java/org/hps/conditions/api/DatabaseObjectException.java
      - copied unchanged from r3250, java/branches/HPSJAVA-488/conditions/src/main/java/org/hps/conditions/api/DatabaseObjectException.java
    java/trunk/conditions/src/main/java/org/hps/conditions/api/FieldValues.java
      - copied unchanged from r3250, java/branches/HPSJAVA-488/conditions/src/main/java/org/hps/conditions/api/FieldValues.java
    java/trunk/conditions/src/main/java/org/hps/conditions/api/FieldValuesMap.java
      - copied unchanged from r3250, java/branches/HPSJAVA-488/conditions/src/main/java/org/hps/conditions/api/FieldValuesMap.java
    java/trunk/conditions/src/main/java/org/hps/conditions/api/TableMetaData.java
      - copied unchanged from r3250, java/branches/HPSJAVA-488/conditions/src/main/java/org/hps/conditions/api/TableMetaData.java
    java/trunk/conditions/src/main/java/org/hps/conditions/api/TableRegistry.java
      - copied unchanged from r3250, java/branches/HPSJAVA-488/conditions/src/main/java/org/hps/conditions/api/TableRegistry.java
    java/trunk/conditions/src/main/java/org/hps/conditions/cli/RunSummaryCommand.java
      - copied unchanged from r3250, java/branches/HPSJAVA-488/conditions/src/main/java/org/hps/conditions/cli/RunSummaryCommand.java
    java/trunk/conditions/src/main/java/org/hps/conditions/dummy/
      - copied from r3250, java/branches/HPSJAVA-488/conditions/src/main/java/org/hps/conditions/dummy/
    java/trunk/conditions/src/main/resources/org/hps/conditions/config/jeremym_dev_connection.prop
      - copied unchanged from r3250, java/branches/HPSJAVA-488/conditions/src/main/resources/org/hps/conditions/config/jeremym_dev_connection.prop
    java/trunk/conditions/src/test/java/org/hps/conditions/api/
      - copied from r3250, java/branches/HPSJAVA-488/conditions/src/test/java/org/hps/conditions/api/
    java/trunk/conditions/src/test/java/org/hps/conditions/dummy/
      - copied from r3250, java/branches/HPSJAVA-488/conditions/src/test/java/org/hps/conditions/dummy/
Removed:
    java/trunk/conditions/src/main/java/org/hps/conditions/api/FieldValueMap.java
    java/trunk/conditions/src/main/java/org/hps/conditions/database/AbstractConditionsObjectConverter.java
    java/trunk/conditions/src/main/java/org/hps/conditions/database/QueryBuilder.java
    java/trunk/conditions/src/main/java/org/hps/conditions/database/TableMetaData.java
    java/trunk/conditions/src/main/java/org/hps/conditions/database/TableRegistry.java
    java/trunk/conditions/src/test/java/org/hps/conditions/database/TableRegistryTest.java
    java/trunk/conditions/src/test/java/org/hps/conditions/ecal/EcalHardwareConditionsTest.java
Modified:
    java/trunk/   (props changed)
    java/trunk/analysis/src/main/java/org/hps/analysis/dataquality/DQMDatabaseManager.java
    java/trunk/conditions/   (props changed)
    java/trunk/conditions/pom.xml
    java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsDriver.java
    java/trunk/conditions/src/main/java/org/hps/conditions/api/AbstractIdentifier.java
    java/trunk/conditions/src/main/java/org/hps/conditions/api/BaseConditionsObject.java
    java/trunk/conditions/src/main/java/org/hps/conditions/api/BaseConditionsObjectCollection.java
    java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsObject.java
    java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectCollection.java
    java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectException.java
    java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectUtilities.java
    java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsRecord.java
    java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsSeries.java
    java/trunk/conditions/src/main/java/org/hps/conditions/api/package-info.java
    java/trunk/conditions/src/main/java/org/hps/conditions/beam/BeamConditions.java
    java/trunk/conditions/src/main/java/org/hps/conditions/beam/BeamCurrent.java
    java/trunk/conditions/src/main/java/org/hps/conditions/beam/ImportBeamConditionsEngRun.java
    java/trunk/conditions/src/main/java/org/hps/conditions/beam/package-info.java
    java/trunk/conditions/src/main/java/org/hps/conditions/cli/AbstractCommand.java
    java/trunk/conditions/src/main/java/org/hps/conditions/cli/AddCommand.java
    java/trunk/conditions/src/main/java/org/hps/conditions/cli/CommandLineTool.java
    java/trunk/conditions/src/main/java/org/hps/conditions/cli/LoadCommand.java
    java/trunk/conditions/src/main/java/org/hps/conditions/cli/PrintCommand.java
    java/trunk/conditions/src/main/java/org/hps/conditions/cli/TagCommand.java
    java/trunk/conditions/src/main/java/org/hps/conditions/cli/package-info.java
    java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsRecordConverter.java
    java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsSeriesConverter.java
    java/trunk/conditions/src/main/java/org/hps/conditions/database/ConnectionParameters.java
    java/trunk/conditions/src/main/java/org/hps/conditions/database/Converter.java
    java/trunk/conditions/src/main/java/org/hps/conditions/database/ConverterRegistry.java
    java/trunk/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java
    java/trunk/conditions/src/main/java/org/hps/conditions/database/DatabaseUtilities.java
    java/trunk/conditions/src/main/java/org/hps/conditions/database/Field.java
    java/trunk/conditions/src/main/java/org/hps/conditions/database/MultipleCollectionsAction.java
    java/trunk/conditions/src/main/java/org/hps/conditions/database/Table.java
    java/trunk/conditions/src/main/java/org/hps/conditions/database/package-info.java
    java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalBadChannel.java
    java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalCalibration.java
    java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalChannel.java
    java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalChannelConstants.java
    java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalConditions.java
    java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalConditionsConverter.java
    java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalConditionsUtil.java
    java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalCrystalChannelMap.java
    java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalGain.java
    java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalLed.java
    java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalLedCalibration.java
    java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalTimeShift.java
    java/trunk/conditions/src/main/java/org/hps/conditions/ecal/TestRunEcalConditionsConverter.java
    java/trunk/conditions/src/main/java/org/hps/conditions/ecal/package-info.java
    java/trunk/conditions/src/main/java/org/hps/conditions/package-info.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtChannel.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtConditions.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtConditionsConverter.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtDaqMapping.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtT0Shift.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/CalibrationHandler.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/ChannelConstants.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/DaqMapHandler.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/MotorPositionLoader.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/OpeningAngleLoader.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtAlignmentConstant.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtBadChannel.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtBiasConditionsLoader.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtCalibration.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtChannel.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditions.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsConverter.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsLoader.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsReader.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConfiguration.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtDaqMapping.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtDetectorSetup.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtGain.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtShapeFitParameters.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtT0Shift.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtTimingConstants.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtTimingConstantsLoader.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtChannel.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtConditions.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtConditionsConverter.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtDaqMapping.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtT0Shift.java
    java/trunk/conditions/src/main/java/org/hps/conditions/svt/package-info.java
    java/trunk/conditions/src/test/java/org/hps/conditions/ConditionsDriverTest.java
    java/trunk/conditions/src/test/java/org/hps/conditions/EngRunConditionsTest.java
    java/trunk/conditions/src/test/java/org/hps/conditions/RunNumberTest.java
    java/trunk/conditions/src/test/java/org/hps/conditions/beam/BeamConditionsTest.java
    java/trunk/conditions/src/test/java/org/hps/conditions/beam/BeamCurrentTest.java
    java/trunk/conditions/src/test/java/org/hps/conditions/database/CollectionIdTest.java
    java/trunk/conditions/src/test/java/org/hps/conditions/database/ConverterRegistryTest.java
    java/trunk/conditions/src/test/java/org/hps/conditions/ecal/EcalLedTest.java
    java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtBadChannelTest.java
    java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtConfigurationTest.java
    java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtDaqMappingTest.java
    java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtDetectorSetupTest.java
    java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtTimingConstantsTest.java
    java/trunk/conditions/src/test/java/org/hps/conditions/svt/TestRunSvtBadChannelsTest.java
    java/trunk/conditions/src/test/java/org/hps/conditions/svt/TestRunSvtConditionsConverterTest.java
    java/trunk/conditions/src/test/java/org/hps/conditions/svt/TestRunSvtDaqMappingTest.java
    java/trunk/conditions/src/test/java/org/hps/conditions/svt/TestRunSvtDetectorSetupTest.java
    java/trunk/distribution/   (props changed)
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalCalibrationsDriver.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalPedestalCalculator.java
    java/trunk/integration-tests/   (props changed)
    java/trunk/monitoring-app/   (props changed)
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsCollectionTableModel.java
    java/trunk/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalLedSequenceMonitor.java

Modified: java/trunk/analysis/src/main/java/org/hps/analysis/dataquality/DQMDatabaseManager.java
 =============================================================================
--- java/trunk/analysis/src/main/java/org/hps/analysis/dataquality/DQMDatabaseManager.java	(original)
+++ java/trunk/analysis/src/main/java/org/hps/analysis/dataquality/DQMDatabaseManager.java	Wed Jul  8 14:47:40 2015
@@ -13,8 +13,8 @@
 import java.util.logging.LogRecord;
 import java.util.logging.Logger;
 
+import org.hps.conditions.api.TableMetaData;
 import org.hps.conditions.database.ConnectionParameters;
-import org.hps.conditions.database.TableMetaData;
 
 /**
  * Manages the DQM database connection and access

Modified: java/trunk/conditions/pom.xml
 =============================================================================
--- java/trunk/conditions/pom.xml	(original)
+++ java/trunk/conditions/pom.xml	Wed Jul  8 14:47:40 2015
@@ -37,7 +37,8 @@
                         <exclude>org/hps/conditions/beam/BeamConditionsTest.java</exclude>
                         <exclude>org/hps/conditions/ecal/EcalHardwareConditionsTest.java</exclude>
                         <exclude>org/hps/conditions/database/CollectionIdTest.java</exclude>
-                        <exclude>/org/hps/conditions/svt/SvtTimingConstantsTest.java</exclude>
+                        <exclude>org/hps/conditions/svt/SvtTimingConstantsTest.java</exclude>
+                        <exclude>org/hps/conditions/dummy/**.java</exclude>
                     </excludes>
                 </configuration>
             </plugin>

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsDriver.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsDriver.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsDriver.java	Wed Jul  8 14:47:40 2015
@@ -5,7 +5,6 @@
 import org.lcsim.util.Driver;
 
 /**
- * <p>
  * This {@link org.lcsim.util.Driver} can be used to customize the behavior of the {@link DatabaseConditionsManager}. It
  * allows the setting of a detector name and run number, as well as other parameters, if the user wishes to override the
  * default behavior of the conditions system, which is generally activated from LCSim events. It is not necessary to run
@@ -13,7 +12,7 @@
  * be included in a steering file.
  * <p>
  * This is an example of using the Driver in an XML steering file:
- * 
+ *
  * <pre>
  * {@code
  * <driver name="ConditionsDriver" type="org.hps.conditions.ConditionsDriver">
@@ -33,26 +32,26 @@
  * end of the hps-distribution. If that class is not being used, then the method must be executed manually at the right
  * time to achieve the proper behavior.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public class ConditionsDriver extends Driver {
 
     /** The name of the detector model. */
     private String detectorName;
 
+    /**
+     * True to freeze the conditions system after activation (requires valid detector name and run number).
+     */
+    private boolean freeze;
+
+    /** The user run number. */
+    private int runNumber = 0;
+
     /** The conditions system tag. */
     private String tag;
 
     /** The XML config resource. */
     private String xmlConfigResource;
-
-    /** The user run number. */
-    private int runNumber = 0;
-
-    /**
-     * True to freeze the conditions system after activation (requires valid detector name and run number).
-     */
-    private boolean freeze;
 
     /**
      * Default constructor.
@@ -61,8 +60,41 @@
     }
 
     /**
+     * Setup the conditions system based on the Driver parameters.
+     *
+     * @throws RuntimeException if there is a problem setting up the conditions system
+     */
+    public final void initialize() {
+
+        final DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
+
+        if (this.xmlConfigResource != null) {
+            // Set a custom XML configuration resource.
+            conditionsManager.setXmlConfig(this.xmlConfigResource);
+        }
+
+        if (this.tag != null) {
+            // Set a tag for filtering ConditionsRecord objects.
+            conditionsManager.setTag(this.tag);
+        }
+        if (this.detectorName != null) {
+            // The manager can only be initialized here if there is a user supplied detector name.
+            try {
+                // Initialize the conditions manager.
+                conditionsManager.setDetector(this.detectorName, this.runNumber);
+                if (this.freeze) {
+                    // User configured to freeze conditions for the job.
+                    conditionsManager.freeze();
+                }
+            } catch (final ConditionsNotFoundException e) {
+                throw new RuntimeException("Error initializing conditions from ConditionsDriver.", e);
+            }
+        }
+    }
+
+    /**
      * Set the name of the detector to use.
-     * 
+     *
      * @param detectorName the name of the detector
      */
     public final void setDetectorName(final String detectorName) {
@@ -74,7 +106,7 @@
      * frozen, the conditions system will ignore subsequent calls to
      * {@link org.lcsim.conditions.ConditionsManager#setDetector(String, int)} and instead use the user supplied
      * detector and run for the whole job.
-     * 
+     *
      * @param freeze <code>true</code> to freeze the conditions system after it is setup
      */
     public final void setFreeze(final boolean freeze) {
@@ -86,7 +118,7 @@
      * that differ from this one, most likely the Driver should be configured to be frozen after setup using
      * {@link #setFreeze(boolean)}. The method {@link #setDetectorName(String)} needs to be called before this one or an
      * exception will be thrown.
-     * 
+     *
      * @param runNumber the user supplied run number for the job
      */
     public final void setRunNumber(final int runNumber) {
@@ -95,7 +127,7 @@
 
     /**
      * Set a tag used to filter ConditionsRecords.
-     * 
+     *
      * @param tag the tag value e.g. "pass0"
      */
     public final void setTag(final String tag) {
@@ -104,43 +136,10 @@
 
     /**
      * Set an XML configuration resource.
-     * 
+     *
      * @param xmlConfigResource the XML configuration resource
      */
     public final void setXmlConfigResource(final String xmlConfigResource) {
         this.xmlConfigResource = xmlConfigResource;
     }
-
-    /**
-     * Setup the conditions system based on the Driver parameters.
-     * 
-     * @throws RuntimeException if there is a problem setting up the conditions system
-     */
-    public final void initialize() {
-
-        final DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
-
-        if (xmlConfigResource != null) {
-            // Set a custom XML configuration resource.
-            conditionsManager.setXmlConfig(xmlConfigResource);
-        }
-
-        if (tag != null) {
-            // Set a tag for filtering ConditionsRecord objects.
-            conditionsManager.setTag(tag);
-        }
-        if (detectorName != null) {
-            // The manager can only be initialized here if there is a user supplied detector name.
-            try {
-                // Initialize the conditions manager.
-                conditionsManager.setDetector(detectorName, runNumber);
-                if (this.freeze) {
-                    // User configured to freeze conditions for the job.
-                    conditionsManager.freeze();
-                }
-            } catch (ConditionsNotFoundException e) {
-                throw new RuntimeException("Error initializing conditions from ConditionsDriver.", e);
-            }
-        }
-    }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/api/AbstractIdentifier.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/api/AbstractIdentifier.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/api/AbstractIdentifier.java	Wed Jul  8 14:47:40 2015
@@ -1,10 +1,9 @@
 package org.hps.conditions.api;
 
 /**
- * This class is a simplistic representation of a packaged identifier for use in
- * the conditions system.
+ * This class is a simplistic representation of a packaged identifier for use in the conditions system.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public abstract class AbstractIdentifier {
 

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/api/BaseConditionsObject.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/api/BaseConditionsObject.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/api/BaseConditionsObject.java	Wed Jul  8 14:47:40 2015
@@ -1,146 +1,443 @@
 package org.hps.conditions.api;
 
-import java.util.Map.Entry;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.text.SimpleDateFormat;
+
+import org.hps.conditions.database.Field;
 
 /**
- * The basic implementation of {@link ConditionsObject}.
+ * This is a basic ORM class for performing CRUD (create, read, update, delete) operations on objects in the conditions
+ * system. Each object is mapped to a single row in a database table.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public class BaseConditionsObject implements ConditionsObject {
 
     /**
-     * The database row ID.
-     */
-    private int rowID = -1;
-
-    /**
-     * The map of field-value pairs.
-     */
-    private FieldValueMap fieldValues;
-
-    /**
-     * Constructor for sub-classing.
+     * Field name for collection ID.
+     */
+    static final String COLLECTION_ID_FIELD = "collection_id";
+
+    /**
+     * Date formatting for insert statement.
+     */
+    static final SimpleDateFormat DEFAULT_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss");
+
+    /**
+     * Value that indicates collection ID is not set (no collection assigned).
+     */
+    static final int UNSET_COLLECTION_ID = -1;
+
+    /**
+     * Value that indicates row ID is not assigned (new record).
+     */
+    static final int UNSET_ROW_ID = -1;
+
+    /**
+     * Perform the default to string operation on a conditions object.
+     *
+     * @param object the conditions object
+     * @return the object converted to a string
+     */
+    protected static String defaultToString(final BaseConditionsObject object) {
+        final StringBuffer sb = new StringBuffer();
+        sb.append(object.getClass().getSimpleName() + " { ");
+        sb.append("id: " + object.getRowId() + ", ");
+        for (final String field : object.getFieldValues().getFieldNames()) {
+            sb.append(field + ": " + object.getFieldValue(Object.class, field) + ", ");
+        }
+        sb.setLength(sb.length() - 2);
+        sb.append(" }");
+        return sb.toString();
+    }
+
+    /**
+     * The JDBC connection used for database operations.
+     */
+    private Connection connection;
+
+    /**
+     * The field values which is a map of key-value pairs corresponding to column values in the database.
+     */
+    private FieldValues fieldValues;
+
+    /**
+     * The row ID of the object in its table. This will be -1 for new objects that are not in the database.
+     */
+    private int rowId = UNSET_ROW_ID;
+
+    /**
+     * The information about the associated table such as the table and column names.
+     */
+    private TableMetaData tableMetaData;
+
+    /**
+     * No argument class constructor; usable by sub-classes only.
      */
     protected BaseConditionsObject() {
-        fieldValues = new FieldValueMap();
-    }
-
-    /**
-     * Get the row ID of this object.
+        this.fieldValues = new FieldValuesMap();
+    }
+
+    /**
+     * Public class constructor.
      * <p>
-     * Implements {@link ConditionsObject#getRowId()}.
+     * This should be used when creating new objects without a list of field values. A new {@link FieldValues} object
+     * will be automatically created from the table information.
+     *
+     * @param connection the database connection
+     * @param tableMetaData the table meta data
+     */
+    public BaseConditionsObject(final Connection connection, final TableMetaData tableMetaData) {
+        this.connection = connection;
+        this.tableMetaData = tableMetaData;
+        this.fieldValues = new FieldValuesMap(tableMetaData);
+    }
+
+    /**
+     * Fully qualified class constructor.
+     * <p>
+     * This should be used when creating new objects from a list of field values.
+     *
+     * @param connection the database connection
+     * @param tableMetaData the table meta data
+     * @param fields the field values
+     */
+    public BaseConditionsObject(final Connection connection, final TableMetaData tableMetaData, final FieldValues fields) {
+        this.connection = connection;
+        this.tableMetaData = tableMetaData;
+        this.fieldValues = fields;
+    }
+
+    /**
+     * Create a SQL insert string for a prepared statement.
+     *
+     * @return the SQL insert string for a prepared statement
+     */
+    private String buildInsertStatement() {
+        final StringBuffer sb = new StringBuffer();
+        sb.append("INSERT INTO " + this.tableMetaData.getTableName() + " (");
+        for (final String fieldName : this.getTableMetaData().getFieldNames()) {
+            sb.append(fieldName + ", ");
+        }
+        sb.setLength(sb.length() - 2);
+        sb.append(") VALUES (");
+        for (final String fieldName : this.getTableMetaData().getFieldNames()) {
+            sb.append("?, ");
+        }
+        sb.setLength(sb.length() - 2);
+        sb.append(")");
+        final String insertSql = sb.toString();
+        return insertSql;
+    }
+
+    /**
+     * Build a SQL update string for a prepared statement.
+     *
+     * @return the SQL update string for a prepared statement
+     */
+    private String buildUpdateStatement() {
+        final StringBuffer sb = new StringBuffer();
+        sb.append("UPDATE " + this.tableMetaData.getTableName() + " SET ");
+        for (final String fieldName : this.tableMetaData.getFieldNames()) {
+            sb.append(fieldName + " = ?, ");
+        }
+        sb.setLength(sb.length() - 2);
+        sb.append(" WHERE id = ?");
+        return sb.toString();
+    }
+
+    /**
+     * Delete the object from the database using its row ID.
+     *
+     * @throws DatabaseObjectException if object is not in the database
+     * @throws SQLException if there is an error performing the delete operation
+     */
+    @Override
+    public final void delete() throws DatabaseObjectException, SQLException {
+        if (this.isNew()) {
+            throw new DatabaseObjectException("Missing valid row ID.", this);
+        }
+        this.connection.setAutoCommit(true);
+        PreparedStatement statement = null;
+        try {
+            statement = this.connection.prepareStatement("DELETE FROM " + this.tableMetaData.getTableName()
+                    + " WHERE id = ?");
+            statement.setInt(1, this.getRowId());
+            statement.executeUpdate();
+            this.rowId = UNSET_ROW_ID;
+        } finally {
+            if (statement != null) {
+                statement.close();
+            }
+        }
+    }
+
+    /**
+     * Get the collection ID of the object.
+     *
+     * @return the collection ID of the object
+     */
+    @Override
+    @Field(names = {"collection_id"})
+    public final Integer getCollectionId() {
+        if (this.fieldValues.isNonNull(COLLECTION_ID_FIELD)) {
+            return this.getFieldValue(Integer.class, COLLECTION_ID_FIELD);
+        } else {
+            return UNSET_COLLECTION_ID;
+        }
+    }
+
+    /**
+     * Get a field value by name.
+     *
+     * @param type the return type
+     * @param name the name of the field
+     */
+    @Override
+    public final <T> T getFieldValue(final Class<T> type, final String name) {
+        return type.cast(this.fieldValues.getValue(type, name));
+    }
+
+    /**
+     * Get a field value.
+     *
+     * @param name the field name
+     * @param T the field value
+     * @param <T> the implicit return return
+     */
+    @Override
+    public <T> T getFieldValue(final String name) {
+        return (T) this.fieldValues.getValue(name);
+    }
+
+    /**
+     * Get the field values.
+     *
+     * @return the field values
+     */
+    @Override
+    public FieldValues getFieldValues() {
+        return this.fieldValues;
+    }
+
+    /**
+     * Get the row ID.
      *
      * @return the row ID
      */
     @Override
     public final int getRowId() {
-        return rowID;
-    }
-
-    /**
-     * True if object is new e.g. not in the database.
+        return this.rowId;
+    }
+
+    /**
+     * Get the table meta data for the object.
+     *
+     * @return the table meta data or <code>null</code> if not set
+     */
+    @Override
+    public final TableMetaData getTableMetaData() {
+        return this.tableMetaData;
+    }
+
+    /**
+     * Return <code>true</code> if collection ID is valid.
+     *
+     * @param <code>true</code> if collection ID is valid
+     */
+    @Override
+    public boolean hasValidCollectionId() {
+        return this.getCollectionId() != UNSET_COLLECTION_ID;
+    }
+
+    /**
+     * Insert the object into the conditions database.
+     */
+    @Override
+    public final void insert() throws DatabaseObjectException, SQLException {
+        if (!this.isNew()) {
+            throw new DatabaseObjectException("Cannot insert existing record with row ID: " + this.getRowId(), this);
+        }
+        if (!this.hasValidCollectionId()) {
+            throw new DatabaseObjectException("Cannot insert object without a valid collection ID.", this);
+        }
+        PreparedStatement insertStatement = null;
+        ResultSet resultSet = null;
+        try {
+            insertStatement = this.connection.prepareStatement(this.buildInsertStatement(),
+                    Statement.RETURN_GENERATED_KEYS);
+            ConditionsObjectUtilities.setupPreparedStatement(insertStatement, this);
+            insertStatement.executeUpdate();
+            resultSet = insertStatement.getGeneratedKeys();
+            resultSet.next();
+            this.rowId = resultSet.getInt(1);
+        } finally {
+            if (resultSet != null) {
+                resultSet.close();
+            }
+            if (insertStatement != null) {
+                insertStatement.close();
+            }
+        }
+    }
+
+    /**
+     * Return <code>true</code> if object is not in the database.
      * <p>
-     * Implements {@link ConditionsObject#isNew()}.
-     *
-     * @return <code>true</code> if object is new
+     * This returns <code>true</code> if the object has a valid row ID.
+     *
+     * @return <code>true</code> if object is not in the database
      */
     @Override
     public final boolean isNew() {
-        return rowID == -1;
-    }
-
-    /**
-     * Set the value of a field.
+        return this.getRowId() == UNSET_ROW_ID;
+    }
+
+    /**
+     * Select a conditions object by its row ID.
+     *
+     * @param id the row ID
+     * @return <code>true</code> is selection was performed
+     */
+    @Override
+    public final boolean select(final int id) throws DatabaseObjectException, SQLException {
+        this.rowId = id;
+        if (id < 1) {
+            throw new IllegalArgumentException("Invalid row ID: " + id);
+        }
+        final StringBuffer sb = new StringBuffer();
+        sb.append("SELECT");
+        for (final String fieldName : this.tableMetaData.getFieldNames()) {
+            sb.append(" " + fieldName + ",");
+        }
+        sb.setLength(sb.length() - 1);
+        sb.append(" FROM " + this.tableMetaData.getTableName());
+        sb.append(" WHERE id = " + this.getRowId());
+        final String sql = sb.toString();
+        Statement statement = null;
+        ResultSet resultSet = null;
+        boolean selected = false;
+        try {
+            statement = this.connection.createStatement();
+            resultSet = statement.executeQuery(sql);
+            selected = resultSet.next();
+            if (selected) {
+                int columnIndex = 1;
+                for (final String fieldName : this.tableMetaData.getFieldNames()) {
+                    this.setFieldValue(fieldName, resultSet.getObject(columnIndex));
+                    ++columnIndex;
+                }
+            }
+        } finally {
+            if (resultSet != null) {
+                resultSet.close();
+            }
+            if (statement != null) {
+                statement.close();
+            }
+        }
+        return selected;
+    }
+
+    /**
+     * Set the collection ID of the object.
+     *
+     * @param collectionId the collection ID of the object
+     */
+    void setCollectionId(final int collectionId) throws ConditionsObjectException {
+        this.setFieldValue(COLLECTION_ID_FIELD, collectionId);
+    }
+
+    /**
+     * Set the JDBC database connection of the object.
+     *
+     * @param connection the database connection of the object
+     */
+    @Override
+    public final void setConnection(final Connection connection) {
+        this.connection = connection;
+    }
+
+    /**
+     * Set a field value.
      * <p>
-     * Implements {@link ConditionsObject#setFieldValue(String, Object)}.
-     *
-     * @param key the name of the field
-     * @param value the value of the field
-     */
-    @Override
-    public final void setFieldValue(final String key, final Object value) {
-        fieldValues.put(key, value);
-    }
-
-    /**
-     * Set all field values using a {@link FieldValueMap}.
+     * Calling this method will flag the object as "dirty" meaning it needs to be updated in the database.
+     *
+     * @param name the name of the field
+     * @param value the new value of the field
+     */
+    @Override
+    public final void setFieldValue(final String name, final Object value) {
+        this.fieldValues.setValue(name, value);
+    }
+
+    /**
+     * Set the field values of the object.
+     *
+     * @param fieldValues the field values of the object
+     */
+    @Override
+    public void setFieldValues(final FieldValues fieldValues) {
+        this.fieldValues = fieldValues;
+    }
+
+    /**
+     * Set the row ID of the object.
+     *
+     * @param rowId the new row ID
+     */
+    void setRowId(final int rowId) {
+        this.rowId = rowId;
+    }
+
+    /**
+     * Set the table meta data of the object.
      * <p>
-     * Implements {@link ConditionsObject#setFieldValues(FieldValueMap)}.
-     *
-     * @param fieldValues the list of key-value pairs
-     */
-    @Override
-    public final void setFieldValues(final FieldValueMap fieldValues) {
-        this.fieldValues = fieldValues;
-    }
-
-    /**
-     * Get the value of a field.
-     * <p>
-     * Implements {@link ConditionsObject#getFieldValue(Class, String)}.
-     *
-     * @param klass the inferred return type
-     * @param field the name of the field
-     * @param <T> the type for inference of return type
-     * @return the value of the field
-     */
-    @Override
-    public final <T> T getFieldValue(final Class<T> klass, final String field) {
-        return klass.cast(fieldValues.get(field));
-    }
-
-    /**
-     * Get the field-value map.
-     * <p>
-     * Implements {@link ConditionsObject#getFieldValues()}.
-     *
-     * @return the field-value map
-     */
-    @Override
-    public final FieldValueMap getFieldValues() {
-        return this.fieldValues;
-    }
-
-    /**
-     * Get a field value.
-     *
-     * @param field the field name
-     * @param <T> the type inferred from the assigned variable
-     * @return the field value
-     */
-    @SuppressWarnings("unchecked")
-    public final <T> T getFieldValue(final String field) {
-        return (T) fieldValues.get(field);
-    }
-
-    /**
-     * Set the database row ID of the object.
-     *
-     * @param rowId the database row ID
-     * @throws ConditionsObjectException if the object already has a row ID
-     */
-    public final void setRowID(final int rowId) throws ConditionsObjectException {
-        if (!isNew()) {
-            throw new ConditionsObjectException("The row ID cannot be reassigned on an existing object.");
-        }
-        this.rowID = rowId;
-    }
-
-    /**
-     * Convert this object to a string, which is a tab-separated row appropriate
-     * for display in a table for console output.
-     *
-     * @return The object converted to a string.
-     */
+     * This sets which table is associated with the object for database operations.
+     *
+     * @param tableMetaData the table meta data
+     */
+    @Override
+    public final void setTableMetaData(final TableMetaData tableMetaData) {
+        this.tableMetaData = tableMetaData;
+    }
+
+    /**
+     * Convert this object to a string.
+     *
+     * @return this object converted to a string
+     */
+    @Override
     public String toString() {
-        final StringBuffer sb = new StringBuffer();
-        sb.append(this.getRowId());
-        sb.append('\t');
-        for (Entry<String, Object> entries : this.getFieldValues().entrySet()) {
-            sb.append(entries.getValue());
-            sb.append('\t');
-        }
-        return sb.toString();
+        return defaultToString(this);
+    }
+
+    /**
+     * Perform an update operation to insert this object's data into the database.
+     *
+     * @return <code>true</code> if an update occurred
+     */
+    @Override
+    public final boolean update() throws DatabaseObjectException, SQLException {
+        int rowsUpdated = 0;
+        if (this.isNew()) {
+            throw new DatabaseObjectException("Cannot perform an update on a new object.", this);
+        }
+        PreparedStatement updateStatement = null;
+        try {
+            updateStatement = this.connection.prepareStatement(this.buildUpdateStatement());
+            updateStatement.setInt(this.fieldValues.getFieldNames().size() + 1, this.getRowId());
+            ConditionsObjectUtilities.setupPreparedStatement(updateStatement, this);
+            rowsUpdated = updateStatement.executeUpdate();
+        } finally {
+            if (updateStatement != null) {
+                updateStatement.close();
+            }
+        }
+        return rowsUpdated != 0;
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/api/BaseConditionsObjectCollection.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/api/BaseConditionsObjectCollection.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/api/BaseConditionsObjectCollection.java	Wed Jul  8 14:47:40 2015
@@ -1,316 +1,734 @@
-package org.hps.conditions.api;
-
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-
-import org.hps.conditions.api.ConditionsObject.DefaultConditionsObjectComparator;
-import org.hps.conditions.database.DatabaseConditionsManager;
-import org.hps.conditions.database.TableMetaData;
-
-/**
- * This class implements a collection API for ConditionsObjects, using a <code>LinkedHashSet</code>.
- *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
- * @param <ObjectType> The concrete type of the collection class.
- */
-@SuppressWarnings("serial")
-public class BaseConditionsObjectCollection<ObjectType extends ConditionsObject> extends LinkedHashSet<ObjectType>
-        implements ConditionsObjectCollection<ObjectType> {
-
-    /**
-     * The associated table meta data.
-     */
-    private TableMetaData tableMetaData = null;
-
-    /**
-     * The collection ID which is -1 if the collection is not in the database.
-     */
-    private int collectionId = -1;
-
-    /**
-     * The associated conditions record information including run validity.
-     */
-    private ConditionsRecord conditionsRecord = null;
-
-    /**
-     * This is the no argument constructor that would be used when creating a new collection that is not in the
-     * database.
-     */
-    public BaseConditionsObjectCollection() {
-    }
-
-    /**
-     * This constructor uses the given conditions record and table meta data objects and will assign the collection ID
-     * from the conditions record.
-     *
-     * @param tableMetaData the table meta data
-     * @param conditionsRecord the conditions record
-     */
-    public BaseConditionsObjectCollection(final ConditionsRecord conditionsRecord, final TableMetaData tableMetaData) {
-        this.conditionsRecord = conditionsRecord;
-        this.tableMetaData = tableMetaData;
-        this.collectionId = conditionsRecord.getCollectionId();
-    }
-
-    /**
-     * This constructor is used to explicitly assign all class variable values.
-     *
-     * @param conditionsRecord the conditions record
-     * @param tableMetaData the table meta data
-     * @param collectionID the new collection ID
-     */
-    public BaseConditionsObjectCollection(final ConditionsRecord conditionsRecord, final TableMetaData tableMetaData,
-            final int collectionID) {
-        this.conditionsRecord = conditionsRecord;
-        this.tableMetaData = tableMetaData;
-        this.collectionId = collectionID;
-    }
-
-    /**
-     * Set the associated table meta data for this collection. Once set it cannot be reassigned, which will cause an
-     * exception to be thrown.
-     *
-     * @param tableMetaData the table meta data for this collection
-     */
-    public final void setTableMetaData(final TableMetaData tableMetaData) {
-        if (this.tableMetaData != null) {
-            throw new RuntimeException("The table meta data cannot be reset once assigned.");
-        }
-        this.tableMetaData = tableMetaData;
-    }
-
-    /**
-     * Set the associated conditions record this collection. Once set it cannot be reassigned, which will cause an
-     * exception to be thrown.
-     *
-     * @param conditionsRecord the conditions record for the collection
-     */
-    public final void setConditionsRecord(final ConditionsRecord conditionsRecord) {
-        if (this.conditionsRecord != null) {
-            throw new RuntimeException("The conditions record cannot be reset once assigned.");
-        }
-        this.conditionsRecord = conditionsRecord;
-    }
-
-    /**
-     * Add an object to the collection.
-     * <p>
-     * Implements {@link ConditionsObjectCollection#add(Object)}.
-     *
-     * @param object the object do add to the collection
-     * @return <code>true</code> if the add operation succeeded
-     */
-    @Override
-    public boolean add(final ObjectType object) {
-        if (contains(object)) {
-            throw new IllegalArgumentException("Cannot add duplicate object " + object + " to collection.");
-        }
-        return super.add(object);
-    }
-
-    /**
-     * Get the table meta data.
-     * <p>
-     * Implements {@link ConditionsObjectCollection#getTableMetaData()}.
-     *
-     * @return the table meta data for the collection.
-     */
-    @Override
-    public final TableMetaData getTableMetaData() {
-        return tableMetaData;
-    }
-
-    /**
-     * Get the collection ID.
-     * <p>
-     * Implements {@link ConditionsObjectCollection#getCollectionId()}.
-     *
-     * @return the collection ID
-     */
-    @Override
-    public final int getCollectionId() {
-        if (conditionsRecord != null) {
-            return conditionsRecord.getCollectionId();
-        } else {
-            return collectionId;
-        }
-    }
-
-    /**
-     * Get the conditions record.
-     * <p>
-     * Implements {@link ConditionsObjectCollection#getConditionsRecord()}.
-     *
-     * @return the conditions record for the collection
-     */
-    @Override
-    public final ConditionsRecord getConditionsRecord() {
-        return conditionsRecord;
-    }
-
-    /**
-     * Set the collection ID. Once set it cannot be assigned again.
-     * <p>
-     * Implements {@link ConditionsObjectCollection#setCollectionId(int)}.
-     *
-     * @param collectionId the new collection ID
-     * @throws ConditionsObjectException if the ID was already assigned
-     */
-    @Override
-    public final void setCollectionId(final int collectionId) throws ConditionsObjectException {
-        if (this.collectionId != -1) {
-            throw new ConditionsObjectException("The collectionId already has the value " + collectionId
-                    + " and cannot be reset.");
-        }
-        this.collectionId = collectionId;
-    }
-
-    /**
-     * Insert the collection into the database.
-     * <p>
-     * Implements {@link ConditionsObjectCollection#insert()}.
-     *
-     * @throws ConditionsObjectException if there was a problem inserting the object
-     * @throws SQLException if there was a SQL syntax error while executing the operation
-     */
-    @Override
-    public final void insert() throws ConditionsObjectException, SQLException {
-        DatabaseConditionsManager.getInstance().insertCollection(this);
-    }
-
-    /**
-     * Select objects into this collection from the database.
-     * <p>
-     * Implements {@link ConditionsObjectCollection#select()}.
-     *
-     * @return the number of records selected
-     */
-    @Override
-    public final int select() {
-        return 0;
-    }
-
-    /**
-     * Delete the collection's object's from the database.
-     * <p>
-     * Implements {@link ConditionsObjectCollection#delete()}.
-     *
-     * @return the number of objects deleted
-     */
-    @Override
-    public int delete() {
-        return 0;
-    }
-
-    /**
-     * Update the collection's objects in the database.
-     * <p>
-     * Implements {@link ConditionsObjectCollection#update()}.
-     *
-     * @return the number of records updated
-     */
-    @Override
-    public final int update() {
-        return 0;
-    }
-
-    /**
-     * Convert this object to a string.
-     * @return the object converted to a string
-     */
-    public String toString() {
-        final StringBuffer buffer = new StringBuffer();
-        for (ConditionsObject object : this) {
-            buffer.append(object.toString());
-            buffer.append('\n');
-        }
-        return buffer.toString();
-    }
-
-    /**
-     * Get an object by index.
-     *
-     * @param index the index in the set
-     * @return the object at the index
-     * @throws IndexOutOfBoundsException if the index is out of bounds
-     */
-    public final ObjectType get(final int index) {
-        if (index + 1 > this.size() || index < 0) {
-            throw new IndexOutOfBoundsException("The index is out of bounds: " + index);
-        }
-        int current = 0;
-        final Iterator<ObjectType> iterator = this.iterator();
-        ObjectType object = iterator.next();
-        while (current != index && iterator.hasNext()) {
-            object = iterator.next();
-            current++;
-        }
-        return object;
-    }
-
-    /**
-     * Sort the collection in place.
-     *
-     * @param comparator the comparator to use for sorting
-     */
-    public void sort(final Comparator<ObjectType> comparator) {
-        final List<ObjectType> objects = new ArrayList<ObjectType>(this);
-        Collections.sort(objects, comparator);
-        clear();
-        addAll(objects);
-    }
-
-    /**
-     * Get a sorted list of the objects, leaving original collection in place.
-     *
-     * @param comparator the comparator to use for the sort
-     * @return a sorted list of the objects
-     */
-    @SuppressWarnings("unchecked")
-    public BaseConditionsObjectCollection<ObjectType> sorted(final Comparator<ObjectType> comparator) {
-        final List<ObjectType> objects = new ArrayList<ObjectType>(this);
-        Collections.sort(objects, comparator);
-        BaseConditionsObjectCollection<ObjectType> collection = null;
-        try {
-            collection = (BaseConditionsObjectCollection<ObjectType>) getClass().newInstance();
-        } catch (InstantiationException | IllegalAccessException e) {
-            throw new RuntimeException(e);
-        }
-        collection.addAll(objects);
-        return collection;
-    }
-
-    /**
-     * Sort this collection in place.
-     */
-    @Override
-    public void sort() {
-        final BaseConditionsObjectCollection<ObjectType> sortedCollection = sorted();
-        this.clear();
-        this.addAll(sortedCollection);
-    }
-
-    /**
-     * Sort and return a copy of the collection.
-     * @return the sorted collection
-     */
-    @SuppressWarnings("unchecked")
-    @Override
-    public BaseConditionsObjectCollection<ObjectType> sorted() {
-        final List<ObjectType> objects = new ArrayList<ObjectType>(this);
-        Collections.sort(objects, new DefaultConditionsObjectComparator());
-        BaseConditionsObjectCollection<ObjectType> collection = null;
-        try {
-            collection = ((BaseConditionsObjectCollection<ObjectType>) getClass().newInstance());
-        } catch (InstantiationException | IllegalAccessException e) {
-            throw new RuntimeException(e);
-        }
-        collection.addAll(objects);
-        return collection;
-    }
-}
+package org.hps.conditions.api;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVParser;
+import org.apache.commons.csv.CSVPrinter;
+import org.apache.commons.csv.CSVRecord;
+
+/**
+ * Implementation of the {@link ConditionsObjectCollection} interface.
+ *
+ * @param <ObjectType> the type of the object contained in this collection
+ * @author Jeremy McCormick, SLAC
+ */
+public class BaseConditionsObjectCollection<ObjectType extends ConditionsObject> implements
+        ConditionsObjectCollection<ObjectType> {
+
+    /**
+     * The collection ID.
+     */
+    private int collectionId = BaseConditionsObject.UNSET_COLLECTION_ID;
+
+    /**
+     * The database connection.
+     */
+    private Connection connection;
+
+    /**
+     * The set of objects contained in the collection (no duplicate references allowed to the same object).
+     */
+    private final Set<ObjectType> objects = new LinkedHashSet<ObjectType>();
+
+    /**
+     * The collection's table meta data mapping it to the database.
+     */
+    private TableMetaData tableMetaData;
+
+    /**
+     * No argument constructor; usable by sub-classes.
+     */
+    protected BaseConditionsObjectCollection() {
+    }
+
+    /**
+     * Constructor with connection and meta data without field values.
+     *
+     * @param connection the database connection
+     * @param tableMetaData the table meta data
+     * @throws SQLException if there
+     * @throws DatabaseObjectException
+     */
+    public BaseConditionsObjectCollection(final Connection connection, final TableMetaData tableMetaData) {
+        this.connection = connection;
+        this.tableMetaData = tableMetaData;
+    }
+
+    /**
+     * Constructor which selects data into the collection using a collection ID.
+     *
+     * @param connection the database connection
+     * @param tableMetaData the table meta data
+     * @param collectionId the collection ID
+     * @throws SQLException if there is an error executing SQL query
+     * @throws DatabaseObjectException if there is an error relating to the conditions object API
+     */
+    public BaseConditionsObjectCollection(final Connection connection, final TableMetaData tableMetaData,
+            final int collectionId) throws SQLException, DatabaseObjectException {
+        this.connection = connection;
+        this.tableMetaData = tableMetaData;
+        this.collectionId = collectionId;
+        if (collectionId != -1) {
+            this.select(collectionId);
+        }
+    }
+
+    /**
+     * Add an object to the collection.
+     *
+     * @param object the object to add to the collection
+     */
+    @Override
+    public boolean add(final ObjectType object) throws ConditionsObjectException {
+        if (object == null) {
+            throw new IllegalArgumentException("The object argument is null.");
+        }
+        // Does this collection have a valid ID yet?
+        if (this.getCollectionId() != BaseConditionsObject.UNSET_COLLECTION_ID) {
+            // Does the object that is being added have a collection ID?
+            if (object.getCollectionId() != BaseConditionsObject.UNSET_COLLECTION_ID) {
+                // Does the object's collection ID not match?
+                if (object.getCollectionId() != this.collectionId) {
+                    // Cannot add an object from a different collection.
+                    throw new IllegalArgumentException("Cannot add object with different collection ID: "
+                            + object.getCollectionId());
+                }
+            } else {
+                try {
+                    // Set the collection ID on the object.
+                    // FIXME: Uses concrete type instead of interface.
+                    ((BaseConditionsObject) object).setCollectionId(this.collectionId);
+                } catch (final ConditionsObjectException e) {
+                    throw new RuntimeException("Error assigning collection ID " + this.collectionId + " to object.", e);
+                }
+            }
+        }
+        final boolean added = this.objects.add(object);
+        if (!added) {
+            throw new RuntimeException("Failed to add object.");
+        }
+        return added;
+    }
+
+    /**
+     * Add all objects from a collection.
+     *
+     * @param collection the collection with objects to add
+     */
+    @Override
+    public void addAll(final ConditionsObjectCollection<ObjectType> collection) {
+        for (final ObjectType object : collection) {
+            this.objects.add(object);
+        }
+    }
+
+    /**
+     * Build a SQL insert statement.
+     *
+     * @return the SQL insert statement
+     */
+    private String buildInsertStatement() {
+        final StringBuffer sb = new StringBuffer();
+        sb.append("INSERT INTO " + this.getTableMetaData().getTableName() + " (");
+        for (final String field : this.getTableMetaData().getFieldNames()) {
+            sb.append(field + ", ");
+        }
+        sb.setLength(sb.length() - 2);
+        sb.append(") VALUES (");
+        for (final String fieldName : this.getTableMetaData().getFieldNames()) {
+            sb.append("?, ");
+        }
+        sb.setLength(sb.length() - 2);
+        sb.append(")");
+        final String updateStatement = sb.toString();
+        return updateStatement;
+    }
+
+    /**
+     * Clear the objects from this collection and reset its ID.
+     * <p>
+     * This has no effect on the underlying database values.
+     */
+    @Override
+    public void clear() {
+        this.objects.clear();
+    }
+
+    /**
+     * Return <code>true</code> if object is contained in this collection.
+     *
+     * @return <code>true</code> if object is contained in this collection
+     */
+    @Override
+    public final boolean contains(final Object object) {
+        return this.objects.contains(object);
+    }
+
+    /**
+     * Delete the objects in the collection from database.
+     *
+     * @throws ConditionsObjectException if there is an error deleting the object
+     * @throws SQLException if there was an error executing the query
+     */
+    @Override
+    public final void delete() throws DatabaseObjectException, SQLException {
+        Statement statement = null;
+        try {
+            final String sql = "DELETE FROM `" + this.tableMetaData.getTableName() + "` WHERE collection_id = '"
+                    + this.getCollectionId() + "'";
+            statement = this.connection.createStatement();
+            statement.executeUpdate(sql);
+        } catch (final SQLException e) {
+            e.printStackTrace();
+        } finally {
+            if (statement != null) {
+                statement.close();
+            }
+        }
+    }
+
+    /**
+     * Return <code>true</code> if collection exists in the database.
+     *
+     * @return <code>true</code> if collection exists in the database
+     * @throws SQLException if there is a query error
+     */
+    private boolean exists() throws SQLException {
+        PreparedStatement statement = null;
+        ResultSet resultSet = null;
+        boolean exists = false;
+        try {
+            statement = this.connection.prepareStatement("SELECT id FROM " + this.tableMetaData.getTableName()
+                    + " where collection_id = ?");
+            statement.setInt(1, this.collectionId);
+            resultSet = statement.executeQuery();
+            exists = resultSet.next();
+        } finally {
+            if (statement != null) {
+                statement.close();
+            }
+            if (resultSet != null) {
+                resultSet.close();
+            }
+        }
+        return exists;
+    }
+
+    /**
+     * Get the object at the index.
+     *
+     * @param index the object index
+     * @return the object at the index
+     * @throws IndexOutOfBoundsException if the index is invalid
+     */
+    @Override
+    public final ObjectType get(final int index) {
+        if (index + 1 > this.size() || index < 0) {
+            throw new IndexOutOfBoundsException("index out of bounds: " + index);
+        }
+        int current = 0;
+        final Iterator<ObjectType> iterator = this.objects.iterator();
+        ObjectType object = iterator.next();
+        while (current != index && iterator.hasNext()) {
+            object = iterator.next();
+            current++;
+        }
+        return object;
+    }
+
+    /**
+     * Get the collection ID.
+     *
+     * @return the collection ID
+     */
+    @Override
+    public final int getCollectionId() {
+        return this.collectionId;
+    }
+
+    /**
+     * Add a row for a new collection in the <i>collections</i> table and return the new collection ID assigned to it.
+     *
+     * @param tableName the name of the table
+     * @param comment an optional comment about this new collection
+     * @return the collection's ID
+     * @throws SQLException
+     */
+    private synchronized int getNextCollectionId() throws SQLException, DatabaseObjectException {
+        final String log = "BaseConditionsObject generated new collection ID";
+        final String description = System.getProperty("user.name") + " created new collection in "
+                + this.tableMetaData.getTableName();
+        PreparedStatement statement = null;
+        ResultSet resultSet = null;
+        int nextCollectionId = -1;
+        try {
+            statement = this.connection.prepareStatement(
+                    "INSERT INTO collections (table_name, log, description, created) VALUES (?, ?, ?, NOW())",
+                    Statement.RETURN_GENERATED_KEYS);
+            statement.setString(1, this.tableMetaData.getTableName());
+            statement.setString(2, log);
+            statement.setString(3, description);
+            statement.execute();
+            resultSet = statement.getGeneratedKeys();
+            if (!resultSet.next()) {
+                throw new DatabaseObjectException("Failed to create new collection record.", this);
+            }
+            nextCollectionId = resultSet.getInt(1);
+        } finally {
+            if (resultSet != null) {
+                resultSet.close();
+            }
+            if (statement != null) {
+                statement.close();
+            }
+        }
+        return nextCollectionId;
+    }
+
+    /**
+     * Get the set of objects in this collection.
+     *
+     * @return the set of objects in this collection
+     */
+    protected Set<ObjectType> getObjects() {
+        return this.objects;
+    }
+
+    /**
+     * Get the table meta data.
+     *
+     * @return the table meta data
+     * @see TableMetaData
+     */
+    @Override
+    public final TableMetaData getTableMetaData() {
+        return this.tableMetaData;
+    }
+
+    /**
+     * Insert the objects from this collection into the database.
+     * <p>
+     * The collection ID will be determined automatically if it is not already set.
+     *
+     * @throws ConditionsObjectException if there is an error inserting the objects
+     * @throws SQLException if there is a query error
+     */
+    @Override
+    public final void insert() throws DatabaseObjectException, SQLException {
+
+        // Turn off auto-commit to perform a transaction.
+        this.connection.setAutoCommit(false);
+
+        if (this.collectionId == BaseConditionsObject.UNSET_COLLECTION_ID) {
+            // Automatically get the next global collection ID from the conditions database.
+            this.collectionId = this.getNextCollectionId();
+        } else {
+            // If the collection already exists in the database with this ID then it cannot be inserted.
+            if (this.exists()) {
+                throw new DatabaseObjectException("The collection " + this.collectionId
+                        + " cannot be inserted because it already exists in the " + this.tableMetaData.getTableName()
+                        + " table.", this);
+            }
+        }
+        // Set collection ID on objects.
+        try {
+            this.setConditionsObjectCollectionIds();
+        } catch (final ConditionsObjectException e) {
+            throw new DatabaseObjectException("Error setting collection IDs on objects.", e, this);
+        }
+        PreparedStatement insertStatement = null;
+        try {
+            insertStatement = this.connection.prepareStatement(this.buildInsertStatement(),
+                    Statement.RETURN_GENERATED_KEYS);
+            for (final ObjectType object : this) {
+                object.setConnection(this.connection);
+                object.setTableMetaData(this.tableMetaData);
+                ConditionsObjectUtilities.setupPreparedStatement(insertStatement, object);
+                insertStatement.executeUpdate();
+                final ResultSet resultSet = insertStatement.getGeneratedKeys();
+                resultSet.next();
+                ((BaseConditionsObject) object).setRowId(resultSet.getInt(1));
+                resultSet.close();
+            }
+            // Commit all the object insert statements together.
+            this.connection.commit();
+        } catch (final SQLException e1) {
+            e1.printStackTrace();
+            if (this.connection != null) {
+                try {
+                    System.err.println("Transaction is being rolled back ...");
+                    this.connection.rollback();
+                } catch (final SQLException e2) {
+                    e2.printStackTrace();
+                }
+            }
+        } finally {
+            if (insertStatement != null) {
+                insertStatement.close();
+            }
+            this.connection.setAutoCommit(true);
+        }
+    }
+
+    /**
+     * Return <code>true</code> if the collection is new, e.g. it is not in the database.
+     *
+     * @return <code>true</code> if the collection is new
+     */
+    @Override
+    public final boolean isNew() {
+        if (this.collectionId == BaseConditionsObject.UNSET_COLLECTION_ID) {
+            return true;
+        }
+        try {
+            // Valid collection ID exists but need to check if inserted into database yet.
+            return this.exists() == false;
+        } catch (final SQLException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Get an iterator for the collection.
+     *
+     * @return an iterator for the collection
+     */
+    @Override
+    public final Iterator<ObjectType> iterator() {
+        return this.objects.iterator();
+    }
+
+    /**
+     * Load data from a CSV file.
+     *
+     * @param file the CSV file
+     */
+    @Override
+    public void loadCsv(final File file) throws IOException, FileNotFoundException,
+            ConditionsObjectException {
+
+        // Clear the objects from the collection.
+        this.objects.clear();
+
+        final TableMetaData tableMetaData = this.getTableMetaData();
+
+        // Check if the table info exists.
+        if (tableMetaData == null) {
+            // Table name is invalid.
+            throw new RuntimeException("The table meta data is not set.");
+        }
+
+        FileReader reader = null;
+        CSVParser parser = null;
+
+        try {
+
+            // Read in the CSV records.
+            reader = new FileReader(file);
+
+            parser = new CSVParser(reader, CSVFormat.DEFAULT.withHeader());
+            final List<CSVRecord> records = parser.getRecords();
+
+            // Get the database field names from the table info.
+            final Set<String> fields = tableMetaData.getFieldNames();
+
+            // Get the text file column headers from the parser.
+            final Map<String, Integer> headerMap = parser.getHeaderMap();
+
+            // Get the headers that were read in from CSV.
+            final Set<String> headers = headerMap.keySet();
+
+            // Make sure the headers are actually valid column names in the database.
+            for (final String header : headerMap.keySet()) {
+                if (!fields.contains(header)) {
+                    // The field name does not match a table column.
+                    throw new RuntimeException("Header " + header + " from CSV is not a column in the "
+                            + tableMetaData.getTableName() + " table.");
+                }
+            }
+
+            // Get the class of the objects contained in this collection.
+            final Class<? extends ConditionsObject> objectClass = this.getTableMetaData().getObjectClass();
+
+            // Iterate over the CSV records.
+            for (final CSVRecord record : records) {
+
+                // Create a new conditions object.
+                final ObjectType object;
+                try {
+                    // Create a new conditions object and cast to correct type for adding to collection.
+                    object = (ObjectType) objectClass.newInstance();
+                } catch (InstantiationException | IllegalAccessException e) {
+                    throw new RuntimeException("Error creating conditions object.", e);
+                }
+
+                // Set the field values on the object.
+                for (final String header : headers) {
+                    // Set the value of a field in the object based on the header name, converting to the correct type.
+                    object.setFieldValue(
+                            header,
+                            ConditionsObjectUtilities.convertValue(this.getTableMetaData().getFieldType(header),
+                                    record.get(header)));
+                }
+
+                // Add the object to the collection.
+                this.add(object);
+            }
+        } finally {
+            // Close the CSV parser and reader.
+            parser.close();
+            reader.close();
+        }
+    }
+
+    /**
+     * Select objects into this collection by their collection ID in the database.
+     *
+     * @return <code>true</code> if at least one object was selected
+     */
+    @Override
+    public final boolean select(final int collectionId) throws SQLException, DatabaseObjectException {
+        this.collectionId = collectionId;
+        Statement statement = null;
+        boolean selected = false;
+        try {
+            statement = this.connection.createStatement();
+            final StringBuffer sb = new StringBuffer();
+            sb.append("SELECT id, ");
+            for (final String fieldName : this.tableMetaData.getFieldNames()) {
+                sb.append(fieldName + ", ");
+            }
+            sb.setLength(sb.length() - 2);
+            sb.append(" FROM " + this.tableMetaData.getTableName() + " WHERE collection_id = " + collectionId);
+            final String sql = sb.toString();
+            final ResultSet resultSet = statement.executeQuery(sql);
+            while (resultSet.next()) {
+                try {
+                    final ObjectType newObject = (ObjectType) this.tableMetaData.getObjectClass().newInstance();
+                    newObject.setConnection(this.connection);
+                    newObject.setTableMetaData(this.tableMetaData);
+                    final int id = resultSet.getInt(1);
+                    ((BaseConditionsObject) newObject).setRowId(id);
+                    int column = 2;
+                    for (final String fieldName : this.tableMetaData.getFieldNames()) {
+                        newObject.setFieldValue(fieldName, resultSet.getObject(column));
+                        ++column;
+                    }
+                    try {
+                        this.add(newObject);
+                    } catch (final ConditionsObjectException e) {
+                        throw new DatabaseObjectException("Error adding object to collection.", e, newObject);
+                    }
+                    selected = true;
+                } catch (InstantiationException | IllegalAccessException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        } finally {
+            if (statement != null) {
+                statement.close();
+            }
+        }
+        return selected;
+    }
+
+    /**
+     * Set the collection ID of this collection.
+     *
+     * @param collectionId the collection ID
+     */
+    @Override
+    public final void setCollectionId(final int collectionId) {
+        this.collectionId = collectionId;
+        try {
+            // Set collection ID on all objects.
+            this.setConditionsObjectCollectionIds();
+        } catch (final ConditionsObjectException e) {
+            throw new RuntimeException("Error setting collection ID on object.", e);
+        }
+    }
+
+    /**
+     * Iterate over the objects in the collection and set their collection IDs.
+     *
+     * @throws ConditionsObjectException if there is an error setting one of the collection IDs
+     */
+    private final void setConditionsObjectCollectionIds() throws ConditionsObjectException {
+        if (this.collectionId != BaseConditionsObject.UNSET_COLLECTION_ID) {
+            for (final ConditionsObject object : this) {
+                ((BaseConditionsObject) object).setCollectionId(this.collectionId);
+            }
+        }
+    }
+
+    /**
+     * Iterate over the objects in the collection and set their database connection reference.
+     */
+    private final void setConditionsObjectConnections() {
+        for (final ConditionsObject object : this) {
+            object.setConnection(this.connection);
+        }
+    }
+
+    /**
+     * Set the database connection of the collection.
+     *
+     * @param connection the database connection of the collection
+     */
+    @Override
+    public final void setConnection(final Connection connection) {
+        this.connection = connection;
+
+        // Set connection on all objects.
+        this.setConditionsObjectConnections();
+    }
+
+    /**
+     * Set the table meta data of the collection.
+     *
+     * @param the table meta data of the collection
+     * @see TableMetaData
+     */
+    @Override
+    public void setTableMetaData(final TableMetaData tableMetaData) {
+        this.tableMetaData = tableMetaData;
+    }
+
+    /**
+     * Get the size of the collection.
+     *
+     * @return the size of the collection
+     */
+    @Override
+    public int size() {
+        return this.objects.size();
+    }
+
+    /**
+     * Sort the collection in place.
+     *
+     * @param comparator the comparison operator to use for sorting
+     */
+    @Override
+    public final void sort(final Comparator<ObjectType> comparator) {
+        final List<ObjectType> list = new ArrayList<ObjectType>(this.objects);
+        Collections.sort(list, comparator);
+        this.objects.clear();
+        this.objects.addAll(list);
+    }
+
+    /**
+     * Return a sorted copy of this collection, leaving the original unchanged.
+     *
+     * @param comparator the comparison class to use for sorting
+     * @return a sorted copy of this collection
+     */
+    @Override
+    public ConditionsObjectCollection<ObjectType> sorted(final Comparator<ObjectType> comparator) {
+        final List<ObjectType> list = new ArrayList<ObjectType>(this.objects);
+        Collections.sort(list, comparator);
+        BaseConditionsObjectCollection<ObjectType> collection;
+        try {
+            collection = this.getClass().newInstance();
+        } catch (InstantiationException | IllegalAccessException e) {
+            throw new RuntimeException("Error creating new collection instance.", e);
+        }
+        for (final ObjectType object : list) {
+            try {
+                collection.add(object);
+            } catch (final ConditionsObjectException e) {
+                throw new RuntimeException("Error adding to new collection in sorted method.", e);
+            }
+        }
+        return collection;
+    }
+
+    /**
+     * Convert object to string.
+     *
+     * @return this object converted to a string
+     */
+    @Override
+    public String toString() {
+        final StringBuffer buff = new StringBuffer();
+        for (final ConditionsObject object : this.getObjects()) {
+            buff.append(object);
+            buff.append('\n');
+        }
+        return buff.toString();
+    }
+
+    /**
+     * Perform database updates on the objects in the collection.
+     *
+     * @return <code>true</code> if at least one object was updated
+     */
+    // FIXME: Rewrite to use PreparedStatement.
+    @Override
+    public boolean update() throws DatabaseObjectException, SQLException {
+        boolean updated = false;
+        for (final ObjectType object : this.objects) {
+            if (object.update() && updated == false) {
+                updated = true;
+            }
+        }
+        return updated;
+    }
+
+    /**
+     * Write contents of this collection to a CSV file.
+     *
+     * @param file the output CSV file
+     */
+    @Override
+    public void writeCsv(final File file) throws IOException {
+        FileWriter fileWriter = null;
+        CSVPrinter csvFilePrinter = null;
+
+        try {
+            fileWriter = new FileWriter(file);
+            csvFilePrinter = new CSVPrinter(fileWriter, CSVFormat.DEFAULT);
+            final List<String> fieldNameList = new ArrayList<String>(this.getTableMetaData().getFieldNames());
+            fieldNameList.remove(BaseConditionsObject.COLLECTION_ID_FIELD);
+            csvFilePrinter.printRecord(fieldNameList);
+            for (final ConditionsObject conditionsObject : this.getObjects()) {
+                final List<Object> record = new ArrayList<Object>();
+                for (final String fieldName : fieldNameList) {
+                    Object value = conditionsObject.getFieldValue(fieldName);
+                    if (value instanceof Date) {
+                        value = BaseConditionsObject.DEFAULT_DATE_FORMAT.format(value);
+                    }
+                    record.add(value);
+                }
+                csvFilePrinter.printRecord(record);
+            }
+        } finally {
+            try {
+                fileWriter.flush();
+                fileWriter.close();
+                csvFilePrinter.close();
+            } catch (final IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+}

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsObject.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsObject.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsObject.java	Wed Jul  8 14:47:40 2015
@@ -1,98 +1,71 @@
 package org.hps.conditions.api;
 
-import java.util.Comparator;
-
 /**
- * This is an ORM interface for accessing conditions information by row from a database table.
+ * This is an interface for connecting conditions information to a database.
+ * <p>
+ * Most of the functionality is derived from the {@link DatabaseObject} interface.
  *
- * @author <a href="mailto:[log in to unmask]>Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
-public interface ConditionsObject {
+public interface ConditionsObject extends DatabaseObject {
 
     /**
-     * Get the row ID of this object, which will be -1 for records not in the database.
+     * Return the collection ID of the object.
      *
-     * @return the database row ID
+     * @return the collection ID of the object
+     */
+    Integer getCollectionId();
+
+    /**
+     * Get the value of a field by casting to an explicit type.
+     *
+     * @param type the return type
+     * @param name the name of the field
+     * @return the field value
+     */
+    <T> T getFieldValue(final Class<T> type, final String name);
+
+    /**
+     * Get the value of a field by casting to an implicit type.
+     *
+     * @param name the name of the field
+     * @return the field value
+     */
+    <T> T getFieldValue(final String name);
+
+    /**
+     * Get the field values for the object.
+     *
+     * @return the field values for the object
+     */
+    FieldValues getFieldValues();
+
+    /**
+     * Get the row ID of the object in the database.
+     *
+     * @return the row ID of the object in the database
      */
     int getRowId();
 
     /**
+     * Return <code>true</code> if object has a valid collection ID.
+     *
+     * @return <code>true</code> if object has a valid collection ID
+     */
+    boolean hasValidCollectionId();
+
+    /**
      * Set the value of a field.
      *
-     * @param field the name of the field
-     * @param value the field value
+     * @param name the name of the field
+     * @param value the new value of the field
      */
-    void setFieldValue(String field, Object value);
+    void setFieldValue(String name, Object value);
 
     /**
-     * Set all of the field values on this object.
+     * Set all of the field values.
      *
-     * @param fieldValues the map containing pairs of field names and values
+     * @param fieldValues the new field values
      */
-    void setFieldValues(FieldValueMap fieldValues);
-
-    /**
-     * Get the map of field values for the object.
-     *
-     * @return the <code>FieldValueMap</code> containing keys and values for the conditions object
-     */
-    FieldValueMap getFieldValues();
-
-    /**
-     * Get a field value, cast to the given class.
-     *
-     * @param field the field value
-     * @param type the class of the field
-     * @param <T> the inferred type of the field
-     * @return the field value cast to type T
-     */
-    <T> T getFieldValue(Class<T> type, String field);
-
-    /**
-     * Get a field value with implicit return type.
-     *
-     * @param field the field's name
-     * @param <T> the inferred type of the field
-     * @return the field value cast to type
-     */
-    <T> T getFieldValue(String field);
-
-    /**
-     * Set the row ID of this object. This cannot be reset once set to a value > 0.
-     *
-     * @param rowId the object's row ID
-     * @throws ConditionsObjectException if already set
-     */
-    void setRowID(int rowId) throws ConditionsObjectException;
-
-    /**
-     * Return true if this object is new, e.g. it does not have a valid row ID. This means that it does not have a
-     * database record in its table.
-     *
-     * @return <code>true</code> if record is new
-     */
-    boolean isNew();
-
-    /**
-     * Default comparator for this interface which uses row ID.
-     */
-    static class DefaultConditionsObjectComparator implements Comparator<ConditionsObject> {
-
-        /**
-         * Compare objects according to standard Java conventions.
-         *
-         * @param o1 the first object
-         * @param o2 the second object
-         * @return the result of comparison operation
-         */
-        public int compare(final ConditionsObject o1, final ConditionsObject o2) {
-            if (o1.getRowId() < o2.getRowId()) {
-                return -1;
-            } else if (o1.getRowId() > o2.getRowId()) {
-                return 1;
-            } else {
-                return 0;
-            }
-        }
-    }
+    void setFieldValues(FieldValues fieldValues);
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectCollection.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectCollection.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectCollection.java	Wed Jul  8 14:47:40 2015
@@ -1,25 +1,57 @@
 package org.hps.conditions.api;
 
-import java.sql.SQLException;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.util.Comparator;
-import java.util.Set;
-
-import org.hps.conditions.database.TableMetaData;
 
 /**
- * An interface representing a collection of conditions objects.
+ * Interface representing a collection of conditions objects.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
- * @param <ObjectType> The type of the conditions object contained in the collection.
+ * @author Jeremy McCormick, SLAC
+ * @param <ObjectType> the type of the objects
  */
-public interface ConditionsObjectCollection<ObjectType extends ConditionsObject> extends Set<ObjectType> {
+public interface ConditionsObjectCollection<ObjectType extends ConditionsObject> extends Iterable<ObjectType>,
+        DatabaseObject {
 
     /**
-     * Get the table meta data.
+     * Add an object to the collection.
      *
-     * @return the table meta data
+     * @param object the object to add to the collection
+     * @return <code>true</code> if object was added successfully
+     * @throws ConditionsObjectException if there was an error adding the object
      */
-    TableMetaData getTableMetaData();
+    boolean add(final ObjectType object) throws ConditionsObjectException;
+
+    /**
+     * Add all objects to the collection.
+     *
+     * @param collection the source collection with objects to add
+     */
+    void addAll(ConditionsObjectCollection<ObjectType> collection);
+
+    /**
+     * Clear the objects from this collection and reset its ID.
+     * <p>
+     * This has no effect on the underlying database values.
+     */
+    void clear();
+
+    /**
+     * Return <code>true</code> if collection contains this object.
+     *
+     * @param object the object to check
+     * @return <code>true</code> if the collection contains the object
+     */
+    boolean contains(Object object);
+
+    /**
+     * Get an object by index.
+     *
+     * @param index the index of the object
+     * @return the object
+     */
+    ObjectType get(final int index);
 
     /**
      * Get the collection ID.
@@ -29,82 +61,50 @@
     int getCollectionId();
 
     /**
-     * Get the conditions record.
+     * Load collection from a CSV file.
      *
-     * @return the conditions record
+     * @param file the input CSV file
+     * @param delimiter the field delimiter (leave blank for default which is comma-delimited)
+     * @throws IOException if there is an error closing the reader
+     * @throws FileNotFoundException if the input file does not exist
+     * @throws ConditionsObjectException if there is an error creating a conditions object
      */
-    ConditionsRecord getConditionsRecord();
+    public void loadCsv(final File file) throws IOException, FileNotFoundException, ConditionsObjectException;
 
     /**
-     * Set the collection ID. Once set it cannot be assigned again, which will cause an exception.
+     * Set the collection ID.
      *
-     * @param collectionId the collection ID
-     * @throws ConditionsObjectException if reassignment of the ID is attempted
+     * @param collectionId the new collection ID
      */
-    void setCollectionId(int collectionId) throws ConditionsObjectException;
+    void setCollectionId(int collectionId);
 
     /**
-     * Insert all objects from the collection into the database.
+     * Get the size of the collection.
      *
-     * @throws ConditionsObjectException if there is a conditions object error
-     * @throws SQLException if there is a SQL syntax or execution error
+     * @return the size of the collection
      */
-    void insert() throws ConditionsObjectException, SQLException;
-
-    /**
-     * Select objects into this collection by collection ID.
-     *
-     * @return the number of rows selected
-     */
-    int select();
-
-    /**
-     * Delete objects in this from the database.
-     *
-     * @return the number of rows deleted
-     */
-    int delete();
-
-    /**
-     * Update rows in the database from these objects.
-     *
-     * @return the number of rows updated
-     */
-    int update();
-
-    /**
-     * Get an object by its index.
-     *
-     * @param index the index in the set
-     * @return the object at the index
-     * @throws IndexOutOfBoundsException if the index value is out of bounds
-     */
-    ObjectType get(int index);
+    int size();
 
     /**
      * Sort the collection in place.
      *
-     * @param comparator the comparator to use for sorting
+     * @param comparator the comparison operator to use for sorting
      */
-    void sort(Comparator<ObjectType> comparator);
+    void sort(final Comparator<ObjectType> comparator);
 
     /**
-     * Get a sorted list of the objects, leaving original collection in place.
+     * Get a sorted copy of the collection, leaving the original in place.
      *
-     * @param comparator the comparator to use for the sort
-     * @return a sorted list of the objects
+     * @param comparator the comparison operator to use
+     * @return the sorted copy of the collection
      */
-    BaseConditionsObjectCollection<ObjectType> sorted(Comparator<ObjectType> comparator);
+    ConditionsObjectCollection<ObjectType> sorted(final Comparator<ObjectType> comparator);
 
     /**
-     * Sort the collection in place.
+     * Write the collection contents to a text file.
+     *
+     * @param file the output text file
+     * @param delimiter the field delimiter (leave blank for default which is comma-delimited)
      */
-    void sort();
-
-    /**
-     * Get a new, sorted collection.
-     *
-     * @return the new sorted collection
-     */
-    BaseConditionsObjectCollection<ObjectType> sorted();
-}
+    void writeCsv(File file) throws IOException;
+}

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectException.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectException.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectException.java	Wed Jul  8 14:47:40 2015
@@ -1,9 +1,9 @@
 package org.hps.conditions.api;
 
-
 /**
- * Thrown by methods of {@link ConditionsObject} or other associated classes
- * such as converters and collections.
+ * Thrown by methods of {@link ConditionsObject} or other associated classes such as converters and collections.
+ *
+ * @author Jeremy McCormick
  */
 @SuppressWarnings("serial")
 public final class ConditionsObjectException extends Exception {
@@ -23,16 +23,6 @@
     }
 
     /**
-     * Error with an associated throwable.
-     *
-     * @param message the error message
-     * @param cause the error's cause
-     */
-    public ConditionsObjectException(final String message, final Throwable cause) {
-        super(message, cause);
-    }
-
-    /**
      * Error with a message and object.
      *
      * @param message the error message
@@ -44,10 +34,21 @@
     }
 
     /**
+     * Error with an associated throwable.
+     *
+     * @param message the error message
+     * @param cause the error's cause
+     */
+    public ConditionsObjectException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
      * Get the associated conditions object to the error.
+     *
      * @return the object associated with the error
      */
     public ConditionsObject getConditionsObject() {
-        return object;
+        return this.object;
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectUtilities.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectUtilities.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectUtilities.java	Wed Jul  8 14:47:40 2015
@@ -1,113 +1,133 @@
 package org.hps.conditions.api;
 
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.util.HashSet;
-import java.util.Set;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Timestamp;
+import java.text.ParseException;
+import java.util.Collection;
+import java.util.Date;
 
-import javassist.Modifier;
-
-import org.hps.conditions.database.Field;
-import org.hps.conditions.database.Table;
-import org.reflections.Reflections;
+import org.hps.conditions.database.DatabaseConditionsManager;
 
 /**
- * This is a collection of utility methods for {@link ConditionsObject}.
+ * This is a collection of utility methods for {@link ConditionsObject}s.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public final class ConditionsObjectUtilities {
+
+    /**
+     * Static instance of conditions manager.
+     */
+    private static final DatabaseConditionsManager MANAGER = DatabaseConditionsManager.getInstance();
+
+    /**
+     * Convert from a raw string into a specific type.
+     *
+     * @param type the target type
+     * @param value the raw value
+     * @return the value converter to the given type
+     */
+    public static Object convertValue(final Class<?> type, final String value) throws ConditionsObjectException {
+        if (Integer.class.equals(type)) {
+            return Integer.parseInt(value);
+        } else if (Double.class.equals(type)) {
+            return Double.parseDouble(value);
+        } else if (Float.class.equals(type)) {
+            return Float.parseFloat(value);
+        } else if (Boolean.class.equals(type)) {
+            return Boolean.parseBoolean(value);
+        } else if (Date.class.equals(type)) {
+            try {
+                return BaseConditionsObject.DEFAULT_DATE_FORMAT.parse(value);
+            } catch (final ParseException e) {
+                throw new ConditionsObjectException("Error parsing date.", e);
+            }
+        } else {
+            return value;
+        }
+    }
+
+    /**
+     * Get the class name of a column.
+     *
+     * @param tableMetaData the table meta data
+     * @param columnName the column name
+     * @return the class name of a column
+     * @throws SQLException if there is a problem querying the database
+     */
+    public static String getColumnClassName(final TableMetaData tableMetaData, final String columnName)
+            throws SQLException {
+        final Statement st = MANAGER.getConnection().createStatement();
+        final ResultSet rs = st.executeQuery("SELECT * from " + tableMetaData.getTableName() + " LIMIT 1");
+        final ResultSetMetaData rsmd = rs.getMetaData();
+        for (int column = 1; column <= rsmd.getColumnCount(); column++) {
+            if (rsmd.getColumnName(column).equals(columnName)) {
+                return rsmd.getColumnClassName(column);
+            }
+        }
+        throw new IllegalArgumentException("unknown columnName: " + columnName);
+    }
+
+    /**
+     * Create a new conditions collection from the table name.
+     *
+     * @param tableName the name of the table
+     * @return the new conditions collection
+     * @throws ConditionsObjectException if there is an error creating the collection
+     */
+    public static ConditionsObjectCollection<?> newCollection(final String tableName) throws ConditionsObjectException {
+        final TableMetaData tableInfo = TableRegistry.getTableRegistry().findByTableName(tableName);
+        final ConditionsObjectCollection<?> collection = tableInfo.newCollection();
+        collection.setConnection(MANAGER.getConnection());
+        return collection;
+    }
+
+    /**
+     * Create a new conditions object from the table name.
+     *
+     * @param tableName the name of the table
+     * @return the new conditions object
+     * @throws ConditionsObjectException if there is an error creating the object
+     */
+    public static ConditionsObject newObject(final String tableName) throws ConditionsObjectException {
+        final TableMetaData tableInfo = TableRegistry.getTableRegistry().findByTableName(tableName);
+        final ConditionsObject object = tableInfo.newObject();
+        object.setConnection(MANAGER.getConnection());
+        return object;
+    }
+
+    /**
+     * Setup a prepared statement from {@link ConditionsObject} data.
+     *
+     * @param statement the SQL <code>PreparedStatement</code>
+     * @param object the {@link ConditionsObject} with the data
+     * @throws SQLException if there is a problem querying the database
+     */
+    public static void setupPreparedStatement(final PreparedStatement statement, final ConditionsObject object)
+            throws SQLException {
+        int column = 1;
+        final TableMetaData tableMetaData = object.getTableMetaData();
+        final Collection<String> fieldNames = tableMetaData.getFieldNames();
+        for (final String fieldName : fieldNames) {
+            Object value = object.getFieldValue(fieldName);
+            if (value != null) {
+                final String className = ConditionsObjectUtilities.getColumnClassName(tableMetaData, fieldName);
+                if (className.equals(Timestamp.class.getName())) {
+                    value = new Timestamp(Date.class.cast(value).getTime());
+                }
+            }
+            statement.setObject(column, value);
+            ++column;
+        }
+    }
 
     /**
      * Do not allow class to be instantiated.
      */
     private ConditionsObjectUtilities() {
     }
-
-    /**
-     * Get the list of table names for the class.
-     *
-     * @param type the class
-     * @return the list of table names
-     */
-    public static String[] getTableNames(final Class<? extends ConditionsObject> type) {
-        final Table tableAnnotation = type.getAnnotation(Table.class);
-        if (tableAnnotation != null) {
-            return tableAnnotation.names();
-        } else {
-            return new String[] {};
-        }
-    }
-
-    /**
-     * Get the list of database field names for the class.
-     *
-     * @param type the class
-     * @return the list of field names
-     */
-    public static Set<String> getFieldNames(final Class<? extends ConditionsObject> type) {
-        final Set<String> fieldNames = new HashSet<String>();
-        for (Method method : type.getMethods()) {
-            if (!method.getReturnType().equals(Void.TYPE)) {
-                for (Annotation annotation : method.getAnnotations()) {
-                    if (annotation.annotationType().equals(Field.class)) {
-                        if (!Modifier.isPublic(method.getModifiers())) {
-                            throw new RuntimeException("The method " + type.getName() + "." + method.getName()
-                                    + " has a Field annotation but is not public.");
-                        }
-                        final Field field = (Field) annotation;
-                        for (String fieldName : field.names()) {
-                            if (fieldName != null && !("".equals(fieldName))) {
-                                fieldNames.add(fieldName);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return fieldNames;
-    }
-
-    /**
-     * Get the class for the collection of the ConditionsObject type.
-     *
-     * @param type the class of the ConditionsObject
-     * @return the class of the collection
-     */
-    @SuppressWarnings("unchecked")
-    public static Class<? extends BaseConditionsObjectCollection<? extends ConditionsObject>> getCollectionType(
-            final Class<? extends ConditionsObject> type) {
-        final String collectionClassName = type.getCanonicalName() + "$" + type.getSimpleName() + "Collection";
-        Class<?> rawCollectionClass;
-        try {
-            rawCollectionClass = Class.forName(collectionClassName);
-        } catch (ClassNotFoundException e) {
-            throw new RuntimeException("The type does not define a nested collection class.", e);
-        }
-        if (!BaseConditionsObjectCollection.class.isAssignableFrom(rawCollectionClass)) {
-            throw new RuntimeException("The class " + rawCollectionClass.getSimpleName()
-                    + " does not extend ConditionsObjectCollection.");
-        }
-        return (Class<? extends BaseConditionsObjectCollection<? extends ConditionsObject>>) rawCollectionClass;
-    }
-
-    /**
-     * Find all available classes that extend ConditionsObject.
-     *
-     * @return The set of all available classes that extend ConditionsObject.
-     */
-    public static Set<Class<? extends ConditionsObject>> findConditionsObjectTypes() {
-        final Reflections reflections = new Reflections("org.hps.conditions");
-        final Set<Class<? extends ConditionsObject>> objectTypes = new HashSet<Class<? extends ConditionsObject>>();
-        for (Class<? extends ConditionsObject> objectType : reflections.getSubTypesOf(ConditionsObject.class)) {
-            if (Modifier.isAbstract(objectType.getModifiers())) {
-                continue;
-            }
-            if (objectType.getAnnotation(Table.class) == null) {
-                continue;
-            }
-            objectTypes.add(objectType);
-        }
-        return objectTypes;
-    }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsRecord.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsRecord.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsRecord.java	Wed Jul  8 14:47:40 2015
@@ -1,26 +1,20 @@
 package org.hps.conditions.api;
 
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Comparator;
 import java.util.Date;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 
 import org.hps.conditions.database.ConditionsRecordConverter;
 import org.hps.conditions.database.Converter;
-import org.hps.conditions.database.DatabaseConditionsManager;
 import org.hps.conditions.database.Field;
-import org.hps.conditions.database.QueryBuilder;
 import org.hps.conditions.database.Table;
-import org.hps.conditions.database.TableMetaData;
 
 /**
  * This class represents a single record from the primary conditions data table, which defines the validity range for a
  * specific collection of conditions objects.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 @Table(names = {"conditions"})
 @Converter(converter = ConditionsRecordConverter.class)
@@ -29,13 +23,13 @@
     /**
      * The concrete collection implementation, including sorting utilities.
      */
-    @SuppressWarnings("serial")
     public static class ConditionsRecordCollection extends BaseConditionsObjectCollection<ConditionsRecord> {
 
         /**
          * Compare conditions records by creation date.
          */
         private static class CreatedComparator implements Comparator<ConditionsRecord> {
+
             /**
              * Compare the creation dates of two conditions records.
              *
@@ -60,6 +54,7 @@
          * Compare conditions records by their key (table name).
          */
         private static class KeyComparator implements Comparator<ConditionsRecord> {
+
             /**
              * Compare the keys (names) of two conditions records.
              *
@@ -78,6 +73,7 @@
          * Compare conditions records by run start.
          */
         private static class RunStartComparator implements Comparator<ConditionsRecord> {
+
             /**
              * Compare the run start numbers of two conditions records.
              *
@@ -100,6 +96,7 @@
          * Compare conditions records by updated date.
          */
         private static class UpdatedComparator implements Comparator<ConditionsRecord> {
+
             /**
              * Compare the updated dates of two conditions records.
              *
@@ -121,6 +118,46 @@
         }
 
         /**
+         * Add a <code>ConditionsRecord</code> to the collection.
+         *
+         * @param object the <code>ConditionsRecord</code> to add to the collection
+         * @return <code>true</code> if object was added
+         */
+        @Override
+        // FIXME: Not sure this method needs to exist.
+        public boolean add(final ConditionsRecord object) throws ConditionsObjectException {
+            if (object == null) {
+                throw new IllegalArgumentException("The object argument is null.");
+            }
+            final boolean added = this.getObjects().add(object);
+            if (!added) {
+                throw new RuntimeException("Failed to add object.");
+            }
+            return added;
+        }
+
+        /**
+         * Find a sub-set of the records matching the key name.
+         * <p>
+         * These will generally map to names of tables.
+         *
+         * @param key the key to find
+         */
+        public ConditionsRecordCollection findByKey(final String key) {
+            final ConditionsRecordCollection collection = new ConditionsRecordCollection();
+            for (final ConditionsRecord record : this) {
+                if (record.getName().equals(key)) {
+                    try {
+                        collection.add(record);
+                    } catch (final ConditionsObjectException e) {
+                        throw new RuntimeException("Error adding record to new collection.", e);
+                    }
+                }
+            }
+            return collection;
+        }
+
+        /**
          * Get the unique conditions keys from the records in this collection.
          *
          * @return the set of unique conditions keys
@@ -134,100 +171,74 @@
         }
 
         /**
-         * Sort the collection in place.
-         *
-         * @param comparator the comparison to use for sorting
-         */
-        @Override
-        public final void sort(final Comparator<ConditionsRecord> comparator) {
-            final List<ConditionsRecord> list = new ArrayList<ConditionsRecord>(this);
-            Collections.sort(list, comparator);
-            this.clear();
-            this.addAll(list);
-        }
-
-        /**
-         * Sort in place by creation date.
+         * Sort the collection in place by creation date.
          */
         public final void sortByCreated() {
-            sort(new CreatedComparator());
-        }
-
-        /**
-         * Sort in place by key.
+            this.sort(new CreatedComparator());
+        }
+
+        /**
+         * Sort the collection in place by key.
          */
         public final void sortByKey() {
-            sort(new KeyComparator());
-        }
-
-        /**
-         * Sort in place by run start.
+            this.sort(new KeyComparator());
+        }
+
+        /**
+         * Sort the collection in place by run start.
          */
         public final void sortByRunStart() {
-            sort(new RunStartComparator());
-        }
-
-        /**
-         * Sort in place by updated date.
+            this.sort(new RunStartComparator());
+        }
+
+        /**
+         * Sort the collection in place by updated date.
          */
         public final void sortByUpdated() {
             this.sort(new UpdatedComparator());
         }
 
         /**
-         * Sort using a comparator and leave the original collection unchanged.
-         *
-         * @param comparator the comparison to use for sorting
+         * Sort and return the collection by creation date.
+         *
          * @return the sorted collection
          */
-        @Override
-        public final ConditionsRecordCollection sorted(final Comparator<ConditionsRecord> comparator) {
-            final List<ConditionsRecord> list = new ArrayList<ConditionsRecord>(this);
-            Collections.sort(list, comparator);
-            final ConditionsRecordCollection collection = new ConditionsRecordCollection();
-            collection.addAll(list);
-            return collection;
-        }
-
-        /**
-         * Sort and return collection by creation date.
+        public final ConditionsRecordCollection sortedByCreated() {
+            return (ConditionsRecordCollection) this.sorted(new CreatedComparator());
+        }
+
+        /**
+         * Sort and return the collection by key (table name).
          *
          * @return the sorted collection
          */
-        public final ConditionsRecordCollection sortedByCreated() {
-            return sorted(new CreatedComparator());
-        }
-
-        /**
-         * Sort and return by key (table name).
+        public final ConditionsRecordCollection sortedByKey() {
+            return (ConditionsRecordCollection) this.sorted(new KeyComparator());
+        }
+
+        /**
+         * Sort and return the collection by run start number.
          *
          * @return the sorted collection
          */
-        public final ConditionsRecordCollection sortedByKey() {
-            return sorted(new KeyComparator());
-        }
-
-        /**
-         * Sort and return by run start number.
+        public final ConditionsRecordCollection sortedByRunStart() {
+            return (ConditionsRecordCollection) this.sorted(new RunStartComparator());
+        }
+
+        /**
+         * Sort and return the collection by updated date.
          *
          * @return the sorted collection
          */
-        public final ConditionsRecordCollection sortedByRunStart() {
-            return sorted(new RunStartComparator());
-        }
-
-        /**
-         * Sort and return collection by updated date.
-         *
-         * @return the sorted collection
-         */
         public final ConditionsRecordCollection sortedByUpdated() {
-            return sorted(new UpdatedComparator());
-        }
-    }
-
-    /**
-     * Create a "blank" conditions record.
+            return (ConditionsRecordCollection) this.sorted(new UpdatedComparator());
+        }
+    }
+
+    /**
+     * Class constructor.
+     * <p>
+     * Creates an empty conditions record.
      */
     public ConditionsRecord() {
     }
@@ -250,12 +261,12 @@
     }
 
     /**
-     * Create a conditions record with fully qualified constructor.
+     * Fully qualified class constructor.
      *
      * @param collectionId the ID of the associated conditions collection
      * @param runStart the starting run number
      * @param runEnd the ending run number
-     * @param name the name of the conditions set (usually same as table name)
+     * @param name the name of the conditions set (usually the same as table name but can be different)
      * @param tableName the name of the conditions data table
      * @param notes text notes about this record
      * @param tag the conditions tag for grouping this record with others
@@ -274,23 +285,13 @@
     }
 
     /**
-     * Get the collection ID, overriding this method from the parent class.
-     *
-     * @return the collection ID
-     */
-    @Field(names = {"collection_id"})
-    public Integer getCollectionId() {
-        return getFieldValue("collection_id");
-    }
-
-    /**
      * Get the date this record was created.
      *
      * @return the date this record was created
      */
     @Field(names = {"created"})
     public Date getCreated() {
-        return getFieldValue("created");
+        return this.getFieldValue("created");
     }
 
     /**
@@ -300,7 +301,7 @@
      */
     @Field(names = {"created_by"})
     public String getCreatedBy() {
-        return getFieldValue("created_by");
+        return this.getFieldValue("created_by");
     }
 
     /**
@@ -311,7 +312,7 @@
      */
     @Field(names = {"name"})
     public String getName() {
-        return getFieldValue("name");
+        return this.getFieldValue("name");
     }
 
     /**
@@ -321,7 +322,7 @@
      */
     @Field(names = {"notes"})
     public String getNotes() {
-        return getFieldValue("notes");
+        return this.getFieldValue("notes");
     }
 
     /**
@@ -331,7 +332,7 @@
      */
     @Field(names = {"run_end"})
     public Integer getRunEnd() {
-        return getFieldValue("run_end");
+        return this.getFieldValue("run_end");
     }
 
     /**
@@ -341,7 +342,7 @@
      */
     @Field(names = {"run_start"})
     public Integer getRunStart() {
-        return getFieldValue("run_start");
+        return this.getFieldValue("run_start");
     }
 
     /**
@@ -351,7 +352,7 @@
      */
     @Field(names = {"table_name"})
     public String getTableName() {
-        return getFieldValue("table_name");
+        return this.getFieldValue("table_name");
     }
 
     /**
@@ -361,7 +362,7 @@
      */
     @Field(names = {"tag"})
     public String getTag() {
-        return getFieldValue("tag");
+        return this.getFieldValue("tag");
     }
 
     /**
@@ -371,30 +372,7 @@
      */
     @Field(names = {"updated"})
     public Date getUpdated() {
-        return getFieldValue("updated");
-    }
-
-    /**
-     * Insert the conditions record into the database.
-     *
-     * @throws ConditionsObjectException if there are errors inserting the record
-     */
-    public void insert() throws ConditionsObjectException {
-        if (getFieldValues().size() == 0) {
-            throw new ConditionsObjectException("There are no field values to insert.");
-        }
-        final TableMetaData tableMetaData = DatabaseConditionsManager.getInstance()
-                .findTableMetaData(ConditionsRecordCollection.class).get(0);
-        if (tableMetaData == null) {
-            throw new ConditionsObjectException("Failed to get meta data for ConditionsRecord.");
-        }
-        final String query = QueryBuilder.buildInsert(tableMetaData.getTableName(), this.getFieldValues());
-        // System.out.println(query);
-        final List<Integer> keys = DatabaseConditionsManager.getInstance().updateQuery(query);
-        if (keys.size() != 1) {
-            throw new ConditionsObjectException("SQL insert returned wrong number of keys: " + keys.size());
-        }
-        setRowID(keys.get(0));
+        return this.getFieldValue("updated");
     }
 
     /**
@@ -405,17 +383,17 @@
     @Override
     public String toString() {
         final StringBuffer sb = new StringBuffer();
-        sb.append("id: " + getRowId() + '\n');
-        sb.append("name: " + getName() + '\n');
-        sb.append("runStart: " + getRunStart() + '\n');
-        sb.append("runEnd: " + getRunEnd() + '\n');
-        sb.append("tableName: " + getTableName() + '\n');
-        sb.append("collectionId: " + getCollectionId() + '\n');
-        sb.append("updated: " + getUpdated() + '\n');
-        sb.append("created: " + getCreated() + '\n');
-        sb.append("tag: " + getTag() + '\n');
-        sb.append("createdBy: " + getCreatedBy() + '\n');
-        sb.append("notes: " + getNotes() + '\n');
+        sb.append("id: " + this.getRowId() + '\n');
+        sb.append("name: " + this.getName() + '\n');
+        sb.append("runStart: " + this.getRunStart() + '\n');
+        sb.append("runEnd: " + this.getRunEnd() + '\n');
+        sb.append("tableName: " + this.getTableName() + '\n');
+        sb.append("collectionId: " + this.getCollectionId() + '\n');
+        sb.append("updated: " + this.getUpdated() + '\n');
+        sb.append("created: " + this.getCreated() + '\n');
+        sb.append("tag: " + this.getTag() + '\n');
+        sb.append("createdBy: " + this.getCreatedBy() + '\n');
+        sb.append("notes: " + this.getNotes() + '\n');
         return sb.toString();
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsSeries.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsSeries.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/api/ConditionsSeries.java	Wed Jul  8 14:47:40 2015
@@ -8,10 +8,10 @@
  *
  * @param <ObjectType> the type of the conditions object
  * @param <CollectionType> the type of the conditions collection
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
-@SuppressWarnings({ "serial" })
-public class 
-    ConditionsSeries<ObjectType extends ConditionsObject, CollectionType extends ConditionsObjectCollection<ObjectType>>
-    extends ArrayList<ConditionsObjectCollection<ObjectType>> {
+@SuppressWarnings({"serial"})
+// FIXME: This class should possibly be removed. It doesn't provide much functionality.
+public class ConditionsSeries<ObjectType extends ConditionsObject, CollectionType extends ConditionsObjectCollection<ObjectType>>
+        extends ArrayList<ConditionsObjectCollection<ObjectType>> {
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/api/package-info.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/api/package-info.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/api/package-info.java	Wed Jul  8 14:47:40 2015
@@ -1,12 +1,11 @@
 /**
- * This package contains interfaces and abstract classes, along with some
- * implementations, of the database conditions API for HPS.  These classes
- * include simple ORM between conditions objects and the database.
+ * Interfaces, abstract classes and implementations of the conditions system API for HPS.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  * @see ConditionsObject
  * @see ConditionsObjectCollection
  * @see ConditionsSeries
  * @see ConditionsRecord
  */
 package org.hps.conditions.api;
+

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/beam/BeamConditions.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/beam/BeamConditions.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/beam/BeamConditions.java	Wed Jul  8 14:47:40 2015
@@ -8,13 +8,11 @@
 import org.hps.conditions.database.Table;
 
 /**
- * Beam-related detector conditions, including current, position
- * in X and Y, and energy.
+ * Beam-related detector conditions, including current, position in X and Y, and energy.
  * <p>
- * Unless otherwise stated, these are assumed to be average values
- * for an entire run.
+ * Unless otherwise stated, these are assumed to be average values for an entire run.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 @Table(names = {"beam"})
 @Converter(multipleCollectionsAction = MultipleCollectionsAction.ERROR)
@@ -34,42 +32,43 @@
     }
 
     /**
-     * Get the average beam current (nA).
-     * A value of 0 indicates there was no beam.
-     * A null value means it was not recorded.
+     * Get the average beam current (nA). A value of 0 indicates there was no beam. A null value means it was not
+     * recorded.
+     *
      * @return the beam current (nA)
      */
     @Field(names = {"current"})
     public Double getCurrent() {
-        return getFieldValue("current");
+        return this.getFieldValue("current");
+    }
+
+    /**
+     * Get the beam energy (GeV). A value of 0 indicates there was no beam. A null value means it was not recorded.
+     *
+     * @return the beam energy
+     */
+    @Field(names = {"energy"})
+    public Double getEnergy() {
+        return this.getFieldValue("energy");
     }
 
     /**
      * Get the average beam position in X (mm).
+     *
      * @return the beam position (mm)
      */
     @Field(names = {"position_x"})
     public Double getPositionX() {
-        return getFieldValue("position_x");
+        return this.getFieldValue("position_x");
     }
 
     /**
      * Get the average beam position in Y (mm).
+     *
      * @return the beam position (mm)
      */
     @Field(names = {"position_y"})
     public Double getPositionY() {
-        return getFieldValue("position_y");
-    }
-
-    /**
-     * Get the beam energy (GeV).
-     * A value of 0 indicates there was no beam.
-     * A null value means it was not recorded.
-     * @return the beam energy
-     */
-    @Field(names = {"energy"})
-    public Double getEnergy() {
-        return getFieldValue("energy");
+        return this.getFieldValue("position_y");
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/beam/BeamCurrent.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/beam/BeamCurrent.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/beam/BeamCurrent.java	Wed Jul  8 14:47:40 2015
@@ -10,7 +10,7 @@
 /**
  * This class is a conditions object for integrated beam current values.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 @Table(names = {"beam_current"})
 @Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED)
@@ -25,10 +25,11 @@
 
     /**
      * Get the integrated beam current.
+     *
      * @return the integrated beam current
      */
     @Field(names = {"beam_current"})
-    public double getIntegratedBeamCurrent() {
-        return getFieldValue("beam_current");
+    public Double getIntegratedBeamCurrent() {
+        return this.getFieldValue("beam_current");
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/beam/ImportBeamConditionsEngRun.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/beam/ImportBeamConditionsEngRun.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/beam/ImportBeamConditionsEngRun.java	Wed Jul  8 14:47:40 2015
@@ -22,7 +22,7 @@
  * <p>
  * The beam energy is hard-coded to 1.92 GeV for now, pending updates with better information.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public final class ImportBeamConditionsEngRun {
 
@@ -95,15 +95,14 @@
         for (final Entry<Integer, BeamConditions> entry : beamMap.entrySet()) {
             final int run = entry.getKey();
             final BeamConditions beam = entry.getValue();
-            final int collectionId = manager.addCollection("beam", "ImportBeamConditionsEngRun created collection by "
-                    + System.getProperty("user.name"), null);
+            System.out.println(beam);
+            final BeamConditionsCollection collection = new BeamConditionsCollection();
+            final int collectionId = manager.getCollectionId(collection, null);
             final ConditionsRecord record = new ConditionsRecord(collectionId, run, run, "beam", "beam",
                     "imported from HPS_Runs.pdf", "eng_run");
             System.out.println(record);
-            System.out.println(beam);
-            final BeamConditionsCollection collection = new BeamConditionsCollection();
             collection.add(beam);
-            manager.insertCollection(collection);
+            collection.insert();
             record.insert();
         }
         manager.closeConnection();

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/beam/package-info.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/beam/package-info.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/beam/package-info.java	Wed Jul  8 14:47:40 2015
@@ -1,6 +1,7 @@
 /**
  * Provides access to beam parameters through the conditions system.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 package org.hps.conditions.beam;
+

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/cli/AbstractCommand.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/cli/AbstractCommand.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/cli/AbstractCommand.java	Wed Jul  8 14:47:40 2015
@@ -8,22 +8,21 @@
 import org.apache.commons.cli.PosixParser;
 
 /**
- * This is the API that sub-commands such as 'load' or 'print' must implement
- * in the conditions command line interface.
+ * This is the API that sub-commands such as 'load' or 'print' must implement in the conditions command line interface.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 abstract class AbstractCommand {
 
     /**
+     * The description of the command.
+     */
+    private final String description;
+
+    /**
      * The name of the (sub)command.
      */
-    private String name;
-
-    /**
-     * The description of the command.
-     */
-    private String description;
+    private final String name;
 
     /**
      * The options this command takes on the command line (Apache CLI).
@@ -36,12 +35,8 @@
     private final Parser parser = new PosixParser();
 
     /**
-     * Verbose setting.
-     */
-    private boolean verbose = false;
-
-    /**
      * Class constructor.
+     *
      * @param name the string that invokes this command
      * @param description the description of this command
      * @param options the command's options (Apache CLI)
@@ -53,7 +48,24 @@
     }
 
     /**
+     * The sub-command execution method that should be implemented by sub-classes.
+     *
+     * @param arguments The command's argument list.
+     */
+    abstract void execute(final String[] arguments);
+
+    /**
+     * Get the description of this command.
+     *
+     * @return the description of this command
+     */
+    protected final String getDescription() {
+        return this.description;
+    }
+
+    /**
      * Get the name of this command.
+     *
      * @return the name of this command
      */
     final String getName() {
@@ -61,55 +73,25 @@
     }
 
     /**
-     * Get the description of this command.
-     * @return the description of this command
-     */
-    protected final String getDescription() {
-        return this.description;
-    }
-
-    /**
      * Get the <code>Options</code> for this command (Apache CLI).
+     *
      * @return the <code>Options</code> object for this command
      */
     protected final Options getOptions() {
-        return options;
-    }
-
-    /**
-     * Print the usage of this sub-command.
-     */
-    protected final void printUsage() {
-        final HelpFormatter help = new HelpFormatter();
-        help.printHelp(getName(), getOptions());
-    }
-
-    /**
-     * Set whether verbose output is enabled.
-     * @param verbose <code>true</code> to enable verbose output
-     */
-    final void setVerbose(final boolean verbose) {
-        this.verbose = verbose;
-    }
-
-    /**
-     * Get verbose flag.
-     * @return the verbose flag
-     */
-    protected boolean getVerbose() {
-        return verbose;
+        return this.options;
     }
 
     /**
      * Parse the sub-command's options.
+     *
      * @param arguments the sub-command's arguments
      * @return the parsed command line
      */
     protected final CommandLine parse(final String[] arguments) {
         CommandLine commandLine = null;
         try {
-            commandLine = parser.parse(options, arguments);
-        } catch (ParseException e) {
+            commandLine = this.parser.parse(this.options, arguments);
+        } catch (final ParseException e) {
             throw new RuntimeException(e);
         }
         if (commandLine.hasOption("h")) {
@@ -120,8 +102,10 @@
     }
 
     /**
-     * The sub-command execution method that should be implemented by sub-classes.
-     * @param arguments The command's argument list.
+     * Print the usage of this sub-command.
      */
-    abstract void execute(final String[] arguments);
+    protected final void printUsage() {
+        final HelpFormatter help = new HelpFormatter();
+        help.printHelp(this.getName(), this.getOptions());
+    }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/cli/AddCommand.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/cli/AddCommand.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/cli/AddCommand.java	Wed Jul  8 14:47:40 2015
@@ -1,5 +1,6 @@
 package org.hps.conditions.cli;
 
+import java.sql.SQLException;
 import java.util.Date;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -7,9 +8,10 @@
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
-import org.hps.conditions.api.ConditionsObjectException;
 import org.hps.conditions.api.ConditionsRecord;
-import org.hps.conditions.api.FieldValueMap;
+import org.hps.conditions.api.DatabaseObjectException;
+import org.hps.conditions.api.FieldValuesMap;
+import org.hps.conditions.api.TableRegistry;
 import org.hps.conditions.database.DatabaseConditionsManager;
 import org.lcsim.util.log.LogUtil;
 
@@ -17,9 +19,9 @@
  * This is a command for the conditions CLI that will add a conditions record, making a conditions set with a particular
  * collection ID available by run number via the {@link org.hps.conditions.database.DatabaseConditionsManager}.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
-public class AddCommand extends AbstractCommand {
+final class AddCommand extends AbstractCommand {
 
     /**
      * Setup logger.
@@ -31,17 +33,17 @@
      */
     private static final Options OPTIONS = new Options();
     static {
-        OPTIONS.addOption(new Option("h", false, "Show help for add command"));
-        OPTIONS.addOption("r", true, "The starting run number (required)");
+        OPTIONS.addOption(new Option("h", false, "print help for add command"));
+        OPTIONS.addOption("r", true, "starting run number (required)");
         OPTIONS.getOption("r").setRequired(true);
-        OPTIONS.addOption("e", true, "The ending run number (default is starting run number)");
-        OPTIONS.addOption("t", true, "The table name (required)");
+        OPTIONS.addOption("e", true, "ending run number (default is starting run number)");
+        OPTIONS.addOption("t", true, "table name (required)");
         OPTIONS.getOption("t").setRequired(true);
-        OPTIONS.addOption("c", true, "The collection ID (required)");
+        OPTIONS.addOption("c", true, "collection ID (required)");
         OPTIONS.getOption("c").setRequired(true);
-        OPTIONS.addOption("T", true, "A tag value (optional)");
-        OPTIONS.addOption("u", true, "Your user name (optional)");
-        OPTIONS.addOption("m", true, "The notes about this conditions set (optional)");
+        OPTIONS.addOption("T", true, "tag value (optional)");
+        OPTIONS.addOption("u", true, "user name (optional)");
+        OPTIONS.addOption("m", true, "notes about this conditions set (optional)");
     }
 
     /**
@@ -64,25 +66,24 @@
      * @param notes the text notes about the collection
      * @return the new conditions record
      */
-    // FIXME: Too many method parameters (max 7 is recommended).
     private ConditionsRecord createConditionsRecord(final int runStart, final int runEnd, final String tableName,
             final String name, final int collectionId, final String createdBy, final String tag, final String notes) {
         final ConditionsRecord conditionsRecord = new ConditionsRecord();
-        final FieldValueMap fieldValues = new FieldValueMap();
-        fieldValues.put("run_start", runStart);
-        fieldValues.put("run_end", runEnd);
-        fieldValues.put("table_name", tableName);
-        fieldValues.put("name", name);
-        fieldValues.put("collection_id", collectionId);
-        fieldValues.put("created_by", createdBy);
+        final FieldValuesMap fieldValues = new FieldValuesMap();
+        fieldValues.setValue("run_start", runStart);
+        fieldValues.setValue("run_end", runEnd);
+        fieldValues.setValue("table_name", tableName);
+        fieldValues.setValue("name", name);
+        fieldValues.setValue("collection_id", collectionId);
+        fieldValues.setValue("created_by", createdBy);
         if (tag != null) {
-            fieldValues.put("tag", tag);
+            fieldValues.setValue("tag", tag);
         }
         if (notes != null) {
-            fieldValues.put("notes", notes);
+            fieldValues.setValue("notes", notes);
         }
         conditionsRecord.setFieldValues(fieldValues);
-        fieldValues.put("created", new Date());
+        fieldValues.setValue("created", new Date());
         return conditionsRecord;
     }
 
@@ -94,13 +95,7 @@
     @Override
     final void execute(final String[] arguments) {
 
-        final CommandLine commandLine = parse(arguments);
-
-        // This command has 3 required options.
-        if (commandLine.getOptions().length == 0) {
-            this.printUsage();
-            System.exit(1);
-        }
+        final CommandLine commandLine = this.parse(arguments);
 
         // Run start (required).
         final int runStart;
@@ -152,17 +147,20 @@
         }
 
         // Create the conditions record to insert.
-        final ConditionsRecord conditionsRecord = createConditionsRecord(runStart, runEnd, tableName, name,
+        final ConditionsRecord conditionsRecord = this.createConditionsRecord(runStart, runEnd, tableName, name,
                 collectionId, createdBy, tag, notes);
+        LOGGER.info("inserting conditions record ..." + '\n' + conditionsRecord);
         try {
             boolean createdConnection = false;
             final DatabaseConditionsManager manager = DatabaseConditionsManager.getInstance();
             if (!DatabaseConditionsManager.getInstance().isConnected()) {
                 createdConnection = manager.openConnection();
             }
+            conditionsRecord.setConnection(manager.getConnection());
+            conditionsRecord.setTableMetaData(TableRegistry.getTableRegistry().findByTableName("conditions"));
             conditionsRecord.insert();
             manager.closeConnection(createdConnection);
-        } catch (final ConditionsObjectException e) {
+        } catch (final SQLException | DatabaseObjectException e) {
             LOGGER.log(Level.SEVERE, "Error adding conditions record", e);
             throw new RuntimeException("An error occurred while adding a conditions record.", e);
         }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/cli/CommandLineTool.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/cli/CommandLineTool.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/cli/CommandLineTool.java	Wed Jul  8 14:47:40 2015
@@ -23,14 +23,26 @@
  * Command line options can be used to supply a custom connection properties file or XML which will override the
  * default.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
-public class CommandLineTool {
+public final class CommandLineTool {
 
     /**
      * Setup logging.
      */
     private static final Logger LOGGER = LogUtil.create(CommandLineTool.class);
+
+    private static Options OPTIONS = new Options();
+
+    static {
+        OPTIONS.addOption(new Option("h", false, "print help"));
+        OPTIONS.addOption(new Option("d", true, "detector name"));
+        OPTIONS.addOption(new Option("r", true, "run number"));
+        OPTIONS.addOption(new Option("p", true, "database connection properties file"));
+        OPTIONS.addOption(new Option("x", true, "conditions XML configuration file"));
+        OPTIONS.addOption(new Option("t", true, "conditions tag to use for filtering records"));
+        OPTIONS.addOption(new Option("l", true, "log level of the conditions manager (INFO, FINE, etc.)"));
+    }
 
     /**
      * Create a basic instance of this class.
@@ -39,16 +51,11 @@
      */
     private static CommandLineTool create() {
         final CommandLineTool cli = new CommandLineTool();
-        cli.options.addOption(new Option("h", false, "Print help and exit"));
-        cli.options.addOption(new Option("d", true, "Set the detector name"));
-        cli.options.addOption(new Option("r", true, "Set the run number"));
-        cli.options.addOption(new Option("v", false, "Enable verbose print output"));
-        cli.options.addOption(new Option("p", true, "Set the database connection properties file"));
-        cli.options.addOption(new Option("x", true, "Set the conditions XML configuration file"));
         cli.registerCommand(new LoadCommand());
         cli.registerCommand(new PrintCommand());
         cli.registerCommand(new AddCommand());
         cli.registerCommand(new TagCommand());
+        cli.registerCommand(new RunSummaryCommand());
         return cli;
     }
 
@@ -72,19 +79,9 @@
     private DatabaseConditionsManager conditionsManager;
 
     /**
-     * The top level options (does not include sub-command options).
-     */
-    private final Options options = new Options();
-
-    /**
      * The options parser.
      */
     private final PosixParser parser = new PosixParser();
-
-    /**
-     * The verbose setting.
-     */
-    private boolean verbose = false;
 
     /**
      * Exit with the given status.
@@ -104,7 +101,7 @@
         for (final String command : this.commands.keySet()) {
             s.append(command + '\n');
         }
-        help.printHelp("CommandLineTool", "Commands:\n" + s.toString(), this.options, "");
+        help.printHelp("CommandLineTool", "Commands:\n" + s.toString(), OPTIONS, "");
     }
 
     /**
@@ -127,34 +124,26 @@
     private void run(final String[] arguments) {
         try {
             if (arguments.length == 0) {
-                printUsage();
-                exit(0);
+                this.printUsage();
+                this.exit(0);
             }
 
             CommandLine commandLine = null;
             try {
-                commandLine = this.parser.parse(this.options, arguments, true);
+                commandLine = this.parser.parse(OPTIONS, arguments, true);
             } catch (final ParseException e) {
-                LOGGER.log(Level.SEVERE, "error parsing the options", e);
-                printUsage();
-                exit(1);
+                LOGGER.log(Level.SEVERE, "Error parsing the options.", e);
+                this.printUsage();
+                this.exit(1);
             }
 
             if (commandLine.hasOption("h") || commandLine.getArgs().length == 0) {
-                printUsage();
-                exit(0);
-            }
-
-            // Set verbosity.
-            if (commandLine.hasOption("v")) {
-                LOGGER.setLevel(Level.ALL);
-                LOGGER.getHandlers()[0].setLevel(Level.ALL);
-                this.verbose = true;
-                LOGGER.config("verbose mode enabled");
+                this.printUsage();
+                this.exit(0);
             }
 
             // Setup conditions manager from command line options.
-            setupConditionsManager(commandLine);
+            this.setupConditionsManager(commandLine);
 
             // Get the sub-command to use.
             final String commandName = commandLine.getArgs()[0];
@@ -167,8 +156,7 @@
             final String[] commandArguments = new String[commandLine.getArgs().length - 1];
             System.arraycopy(commandLine.getArgs(), 1, commandArguments, 0, commandArguments.length);
 
-            // Excecute the sub-command.
-            command.setVerbose(this.verbose);
+            // Execute the sub-command.
             command.execute(commandArguments);
         } catch (final Exception e) {
             e.printStackTrace();
@@ -185,62 +173,83 @@
      */
     private void setupConditionsManager(final CommandLine commandLine) {
 
-        LOGGER.info("setting up conditions manager");
+        LOGGER.info("Setting up the conditions manager ...");
 
         // Create new manager.
         this.conditionsManager = DatabaseConditionsManager.getInstance();
 
-        // Set log level.
-        this.conditionsManager.setLogLevel(LOGGER.getLevel());
+        // Set the conditions manager log level (does not affect logger of this class or sub-commands).
+        if (commandLine.hasOption("l")) {
+            final Level level = Level.parse(commandLine.getOptionValue("l"));
+            this.conditionsManager.setLogLevel(level);
+            LOGGER.config("conditions manager log level will be set to " + level.toString());
+        }
 
         // Connection properties.
         if (commandLine.hasOption("p")) {
             final File connectionPropertiesFile = new File(commandLine.getOptionValue("p"));
             this.conditionsManager.setConnectionProperties(connectionPropertiesFile);
-            LOGGER.config("connection properties -p " + connectionPropertiesFile);
-        }
-
-        // XML config.
+            LOGGER.config("using connection properties " + connectionPropertiesFile.getPath());
+        }
+
+        // Conditions system XML configuration file.
         if (commandLine.hasOption("x")) {
             final File xmlConfigFile = new File(commandLine.getOptionValue("x"));
             this.conditionsManager.setXmlConfig(xmlConfigFile);
-            LOGGER.config("XML config -x " + xmlConfigFile);
+            LOGGER.config("using XML config " + xmlConfigFile.getPath());
+        }
+
+        // User specified tag of conditions records.
+        if (commandLine.hasOption("t")) {
+            final String tag = commandLine.getOptionValue("t");
+            this.conditionsManager.setTag(tag);
+            LOGGER.config("using tag " + tag);
         }
 
         // If there is a run number or detector number then attempt to initialize the conditions system.
         if (commandLine.hasOption("r") || commandLine.hasOption("d")) {
 
-            LOGGER.config("detector name or run number supplied so manager will be initialized");
+            if (!commandLine.hasOption("r")) {
+                // Missing run number.
+                throw new RuntimeException(
+                        "Missing -r option with run number which must be given when detector name is used.");
+            }
+
+            if (!commandLine.hasOption("d")) {
+                // Missing detector name.
+                throw new RuntimeException(
+                        "Missing -d option with detector name which must be given when run number is used.");
+            }
 
             // Set detector name.
             String detectorName = null;
             if (commandLine.hasOption("d")) {
                 detectorName = commandLine.getOptionValue("d");
-                LOGGER.config("detector -d " + detectorName);
+                LOGGER.config("using detector " + detectorName);
             } else {
                 detectorName = "HPS-ECalCommissioning-v2";
-                LOGGER.config("default detector " + detectorName + " is being used");
             }
 
             // Get run number.
             Integer run = null;
             if (commandLine.hasOption("r")) {
                 run = Integer.parseInt(commandLine.getOptionValue("r"));
-                LOGGER.config("run -r " + run);
+                LOGGER.config("using run " + run);
             } else {
                 run = 0;
-                LOGGER.config("default run number " + run + " is being used");
             }
 
             // Setup the conditions manager with user detector name and run number.
             try {
-                LOGGER.config("initializing conditions manager with detector " + detectorName + " and run " + run);
+                LOGGER.config("Initializing conditions manager with detector " + detectorName + " and run " + run
+                        + " ...");
                 DatabaseConditionsManager.getInstance().setDetector(detectorName, run);
-                LOGGER.config("conditions manager initialized successfully");
+                LOGGER.config("Conditions manager was initialized successfully!");
                 LOGGER.getHandlers()[0].flush();
             } catch (final ConditionsNotFoundException e) {
-                throw new RuntimeException(e);
-            }
-        }
+                throw new RuntimeException("Error setting up the conditions manager.", e);
+            }
+        }
+        LOGGER.info("Done setting up the conditions manager!");
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/cli/LoadCommand.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/cli/LoadCommand.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/cli/LoadCommand.java	Wed Jul  8 14:47:40 2015
@@ -1,64 +1,58 @@
 package org.hps.conditions.cli;
 
-import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
 import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringTokenizer;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
+import org.hps.conditions.api.BaseConditionsObjectCollection;
+import org.hps.conditions.api.ConditionsObject;
+import org.hps.conditions.api.DatabaseObjectException;
+import org.hps.conditions.api.TableMetaData;
 import org.hps.conditions.database.DatabaseConditionsManager;
-import org.hps.conditions.database.QueryBuilder;
 import org.lcsim.util.log.LogUtil;
+import org.lcsim.util.log.MessageOnlyLogFormatter;
 
 /**
- * This is a sub-command to add conditions data using an input text file. The file should be ASCII text that is tab or
- * space delimited and includes headers with the names of the database columns. (These must match exactly!) The user
- * must supply a table name as the target for the SQL insert. An optional collection ID can be supplied, which may not
- * exist already in the table. Otherwise, the command will fail. By default, the next collection ID will be found by the
- * conditions manager.
- * <p>
+ * This is a sub-command to add conditions data using an input text file. The file should be ASCII text that is
+ * delimited consistently by a single character. The user must supply a table name as the target for the SQL insert. An
+ * optional collection ID can be supplied, which is not allowed to exist already in the table. Otherwise, the command
+ * will fail. By default, the next collection ID will be found by the conditions manager.
  *
- * <pre>
- * java -cp hps-distribution-bin.jar org.hps.conditions.cli.CommandLineTool \
- *     -p conditions_dev_local.properties load -t scratch_svt_gains -f ./scratch_svt_gains.txt -c 1
- * </pre>
- *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
-class LoadCommand extends AbstractCommand {
+final class LoadCommand extends AbstractCommand {
 
     /**
-     * Setup logger.
+     * Setup the logger.
      */
-    private static final Logger LOGGER = LogUtil.create(LoadCommand.class);
+    private static final Logger LOGGER = LogUtil.create(LoadCommand.class, new MessageOnlyLogFormatter(), Level.ALL);
 
     /**
      * Define command options.
      */
     private static final Options OPTIONS = new Options();
     static {
-        OPTIONS.addOption(new Option("h", false, "Show help for load command"));
-        OPTIONS.addOption(new Option("t", true, "Name of the target table in the database"));
-        OPTIONS.addOption(new Option("f", true, "Input data file"));
-        OPTIONS.addOption(new Option("d", true, "Description of collection data"));
+        OPTIONS.addOption(new Option("h", false, "print help for load command"));
+        OPTIONS.addOption(new Option("t", true, "name of the target table (required)"));
+        OPTIONS.getOption("t").setRequired(true);
+        OPTIONS.addOption(new Option("f", true, "input data file path (required)"));
+        OPTIONS.getOption("f").setRequired(true);
+        OPTIONS.addOption(new Option("d", true, "description for the collection log"));
     }
 
     /**
      * Class constructor.
      */
     LoadCommand() {
-        super("load", "Load a set of conditions into the database from a text file", OPTIONS);
+        super("load", "Create a new conditions collection in the database from an input text file", OPTIONS);
     }
 
     /**
-     * Execute the 'load' command with the given arguments.
+     * Execute the <i>load</i> command with the given arguments.
      *
      * @param arguments the command arguments
      */
@@ -87,74 +81,47 @@
             openedConnection = conditionsManager.openConnection();
         }
 
-        String collectionDescription = null;
+        String description = null;
         if (commandLine.hasOption("d")) {
-            collectionDescription = commandLine.getOptionValue("d");
+            description = commandLine.getOptionValue("d");
         }
 
-        int collectionId;
+        final TableMetaData tableMetaData = conditionsManager.findTableMetaData(tableName);
+        if (tableMetaData == null) {
+            throw new IllegalArgumentException("No table meta data found for " + tableName);
+        }
+        LOGGER.info("found tableMetaData for " + tableMetaData.getTableName());
+        final BaseConditionsObjectCollection<ConditionsObject> newCollection = new BaseConditionsObjectCollection<ConditionsObject>(
+                conditionsManager.getConnection(), tableMetaData);
+
+        LOGGER.info("getting new collection ID ...");
+
         try {
-            collectionId = conditionsManager.addCollection(tableName,
-                    "loaded with command line client by " + System.getProperty("user.name"), collectionDescription);
+            conditionsManager.getCollectionId(newCollection, description);
         } catch (final SQLException e) {
-            throw new RuntimeException("Error getting new collection ID.", e);
+            throw new RuntimeException("Error getting collection ID.", e);
         }
 
-        final List<String> columnNames = new ArrayList<String>();
-        final List<List<String>> rows = new ArrayList<List<String>>();
-        this.parseFile(fileName, columnNames, rows);
+        LOGGER.info("collection was assigned ID " + newCollection.getCollectionId());
 
-        final String insertSql = QueryBuilder.buildInsert(tableName, collectionId, columnNames, rows);
-        if (this.getVerbose()) {
-            LOGGER.info(insertSql);
+        LOGGER.info("parsing input file " + fileName + " ...");
+        try {
+            newCollection.loadCsv(new File(fileName));
+        } catch (final Exception e) {
+            throw new RuntimeException("Error loading CSV file.", e);
         }
-        // FIXME: This call should go through an object API like ConditionsObjectCollection.insert rather than the
-        // manager directly.
-        final List<Integer> ids = conditionsManager.updateQuery(insertSql);
-        LOGGER.info("Inserted " + ids.size() + " new rows into table " + tableName + " with collection_id "
-                + collectionId);
+        LOGGER.info("Done parsing input file!");
+
+        try {
+            LOGGER.info("Inserting collection ...");
+            newCollection.insert();
+            LOGGER.info("Done inserting collection!");
+        } catch (SQLException | DatabaseObjectException e) {
+            throw new RuntimeException("Error getting collection ID.", e);
+        }
+
         conditionsManager.closeConnection(openedConnection);
-    }
 
-    /**
-     * Parse an input text file and add column names and row data to the input lists.
-     *
-     * @param fileName the name of the text file
-     * @param columnNames the list of columns (modified by this method)
-     * @param rows the list of rows (modified by this method)
-     */
-    private final void parseFile(final String fileName, final List<String> columnNames, final List<List<String>> rows) {
-        final File inputFile = new File(fileName);
-        BufferedReader reader = null;
-        try {
-            reader = new BufferedReader(new FileReader(inputFile));
-            final String headerLine = reader.readLine();
-            if (headerLine == null) {
-                throw new IllegalArgumentException("The file is empty.");
-            }
-            StringTokenizer tokenizer = new StringTokenizer(headerLine, " \t");
-            while (tokenizer.hasMoreTokens()) {
-                columnNames.add(tokenizer.nextToken().trim());
-            }
-            String line = null;
-            while ((line = reader.readLine()) != null) {
-                tokenizer = new StringTokenizer(line, " \t");
-                final List<String> row = new ArrayList<String>();
-                while (tokenizer.hasMoreTokens()) {
-                    row.add(tokenizer.nextToken().trim());
-                }
-                rows.add(row);
-            }
-        } catch (final Exception e) {
-            throw new RuntimeException(e);
-        } finally {
-            if (reader != null) {
-                try {
-                    reader.close();
-                } catch (final IOException e) {
-                    e.printStackTrace();
-                }
-            }
-        }
+        LOGGER.info("Collection was loaded successfully!");
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/cli/PrintCommand.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/cli/PrintCommand.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/cli/PrintCommand.java	Wed Jul  8 14:47:40 2015
@@ -16,17 +16,17 @@
 import org.hps.conditions.api.ConditionsObject;
 import org.hps.conditions.api.ConditionsObjectCollection;
 import org.hps.conditions.api.ConditionsRecord.ConditionsRecordCollection;
+import org.hps.conditions.api.TableMetaData;
 import org.hps.conditions.database.DatabaseConditionsManager;
-import org.hps.conditions.database.TableMetaData;
 import org.lcsim.util.log.LogUtil;
 
 /**
  * This sub-command of the conditions CLI prints conditions conditions table data by run number to the console or
  * optionally writes it to an output file.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
-class PrintCommand extends AbstractCommand {
+final class PrintCommand extends AbstractCommand {
 
     /**
      * Setup logger.
@@ -39,13 +39,12 @@
     static Options options = new Options();
 
     static {
-        options.addOption(new Option("h", false, "Show help for print command"));
-        options.addOption(new Option("t", true, "Set the table name"));
-        options.addOption(new Option("i", false, "Print the ID for the records (off by default)"));
-        options.addOption(new Option("f", true, "Write print output to a file (must be used with -t option)"));
-        options.addOption(new Option("H", false, "Suppress printing of conditions record and table info"));
-        options.addOption(new Option("d", false, "Use tabs for field delimiter instead of spaces"));
-        options.addOption(new Option("T", true, "Specify a conditions tag to use for filtering records"));
+        options.addOption(new Option("h", false, "print help for print command"));
+        options.addOption(new Option("t", true, "table name"));
+        options.addOption(new Option("i", false, "print the ID for the records (off by default)"));
+        options.addOption(new Option("f", true, "write print output to a file (must be used with -t option)"));
+        options.addOption(new Option("H", false, "suppress printing of conditions record and table info"));
+        options.addOption(new Option("d", false, "use tabs for field delimiter instead of spaces"));
     }
 
     /**
@@ -88,17 +87,12 @@
     @Override
     final void execute(final String[] arguments) {
 
-        final CommandLine commandLine = parse(arguments);
+        final CommandLine commandLine = this.parse(arguments);
 
         final DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
 
         if (!conditionsManager.isInitialized()) {
             throw new RuntimeException("conditions system is not initialized");
-        }
-
-        // User specified tag of conditions records.
-        if (commandLine.hasOption("T")) {
-            conditionsManager.setTag(commandLine.getOptionValue("T"));
         }
 
         // Print conditions sets matching a specific conditions key.
@@ -160,7 +154,7 @@
         final Set<String> conditionsKeys = conditionsRecords.getConditionsKeys();
 
         // Print the records and the data.
-        printConditionsRecords(conditionsKeys);
+        this.printConditionsRecords(conditionsKeys);
         this.ps.flush();
         this.ps.close();
 
@@ -178,8 +172,10 @@
         final StringBuffer buffer = new StringBuffer();
         for (final Object object : collection) {
             for (final String columnName : collection.getTableMetaData().getFieldNames()) {
-                buffer.append(((ConditionsObject) object).getFieldValue(columnName));
-                buffer.append(this.fieldDelimiter);
+                if (!"collection_id".equals(columnName)) {
+                    buffer.append(((ConditionsObject) object).getFieldValue(columnName));
+                    buffer.append(this.fieldDelimiter);
+                }
             }
             buffer.setLength(buffer.length() - 1);
             buffer.append('\n');
@@ -195,8 +191,9 @@
      * @param collection the collection
      */
     private void printCollectionHeader(final ConditionsObjectCollection<?> collection) {
-        LOGGER.info('\n' + "--------------------------------------" + '\n' + collection.getConditionsRecord()
-                + "--------------------------------------");
+        LOGGER.info('\n' + "--------------------------------------" + '\n' + "table: "
+                + collection.getTableMetaData().getTableName() + '\n' + "collection ID: "
+                + collection.getCollectionId() + '\n' + "--------------------------------------");
     }
 
     /**
@@ -208,10 +205,10 @@
         // Loop over all the collections and print them.
         for (final ConditionsObjectCollection<?> collection : collectionList) {
             if (this.printHeaders) {
-                printCollectionHeader(collection);
-            }
-            printColumnNames(collection.getTableMetaData());
-            printCollection(collection);
+                this.printCollectionHeader(collection);
+            }
+            this.printColumnNames(collection.getTableMetaData());
+            this.printCollection(collection);
             this.ps.println();
         }
         this.ps.flush();
@@ -228,8 +225,10 @@
             this.ps.print(this.fieldDelimiter);
         }
         for (final String columnName : tableMetaData.getFieldNames()) {
-            this.ps.print(columnName);
-            this.ps.print(this.fieldDelimiter);
+            if (!"collection_id".equals(columnName)) {
+                this.ps.print(columnName);
+                this.ps.print(this.fieldDelimiter);
+            }
         }
         this.ps.println();
     }
@@ -271,7 +270,7 @@
             collectionList.add(collection);
 
             // Print out all the collection data to console or file.
-            printCollections(collectionList);
+            this.printCollections(collectionList);
         }
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/cli/TagCommand.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/cli/TagCommand.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/cli/TagCommand.java	Wed Jul  8 14:47:40 2015
@@ -10,19 +10,20 @@
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
-import org.hps.conditions.api.ConditionsObjectCollection;
 import org.hps.conditions.api.ConditionsObjectException;
 import org.hps.conditions.api.ConditionsRecord;
+import org.hps.conditions.api.TableRegistry;
 import org.hps.conditions.api.ConditionsRecord.ConditionsRecordCollection;
+import org.hps.conditions.api.DatabaseObjectException;
+import org.hps.conditions.api.TableMetaData;
 import org.hps.conditions.database.DatabaseConditionsManager;
-import org.hps.conditions.database.TableMetaData;
 import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
 import org.lcsim.util.log.LogUtil;
 
 /**
  * Create a conditions system tag.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public class TagCommand extends AbstractCommand {
 
@@ -67,9 +68,12 @@
     @Override
     void execute(final String[] arguments) {
 
-        final CommandLine commandLine = parse(arguments);
+        final CommandLine commandLine = this.parse(arguments);
 
         final Set<Integer> runNumbers = new LinkedHashSet<Integer>();
+        if (commandLine.getOptionValues("r") == null) {
+            throw new RuntimeException("Missing -r argument with list of run numbers.");
+        }
         for (final String value : commandLine.getOptionValues("r")) {
             runNumbers.add(Integer.parseInt(value));
         }
@@ -105,11 +109,8 @@
                 throw new RuntimeException(e);
             }
 
-            // The records from this run.
-            final ConditionsRecordCollection records = manager.getConditionsRecords();
-
             // The unique conditions keys from this run.
-            final Set<String> keys = records.getConditionsKeys();
+            final Set<String> keys = manager.getConditionsRecords().getConditionsKeys();
 
             // Scan through all the unique keys.
             for (final String key : keys) {
@@ -117,12 +118,13 @@
                 // Get the table meta data for the key.
                 final TableMetaData tableMetaData = manager.findTableMetaData(key);
 
-                // Get the default collection for this key in the run.
-                final ConditionsObjectCollection<?> collection = manager.getCachedConditions(
-                        tableMetaData.getCollectionClass(), tableMetaData.getTableName()).getCachedData();
+                // Get the ConditionsRecord from the collection.
+                final ConditionsRecordCollection records = manager.findConditionsRecords(key);
+                records.sortByUpdated();
+                final ConditionsRecord record = records.get(records.size() - 1);
 
-                // Get the ConditionsRecord from the collection.
-                final ConditionsRecord record = collection.getConditionsRecord();
+                manager.getCachedConditions(tableMetaData.getCollectionClass(), tableMetaData.getTableName())
+                        .getCachedData();
 
                 // Is this record already part of the new tag?
                 if (!addedIds.contains(record.getRowId())) {
@@ -133,7 +135,11 @@
                     newRecord.setFieldValue("tag", newTag);
 
                     // Add the record to the tag.
-                    tagRecords.add(newRecord);
+                    try {
+                        tagRecords.add(newRecord);
+                    } catch (final ConditionsObjectException e) {
+                        throw new RuntimeException(e);
+                    }
 
                     // Flag the record's ID as used so it is only added once.
                     addedIds.add(record.getRowId());
@@ -160,8 +166,10 @@
         // Create the tag in the database if user verified or force option was present.
         if (makeTag) {
             try {
+                tagRecords.setConnection(manager.getConnection());
+                tagRecords.setTableMetaData(TableRegistry.getTableRegistry().findByTableName("conditions"));
                 tagRecords.insert();
-            } catch (ConditionsObjectException | SQLException e) {
+            } catch (DatabaseObjectException | SQLException e) {
                 throw new RuntimeException(e);
             }
         }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/cli/package-info.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/cli/package-info.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/cli/package-info.java	Wed Jul  8 14:47:40 2015
@@ -1,6 +1,7 @@
 /**
  * Command line interface to the conditions system.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 package org.hps.conditions.cli;
+

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsRecordConverter.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsRecordConverter.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsRecordConverter.java	Wed Jul  8 14:47:40 2015
@@ -3,15 +3,20 @@
 import java.sql.ResultSet;
 import java.sql.SQLException;
 
-import org.hps.conditions.api.BaseConditionsObjectCollection;
+import org.hps.conditions.api.AbstractConditionsObjectConverter;
 import org.hps.conditions.api.ConditionsObject;
+import org.hps.conditions.api.ConditionsObjectCollection;
+import org.hps.conditions.api.ConditionsObjectException;
+import org.hps.conditions.api.ConditionsRecord;
 import org.hps.conditions.api.ConditionsRecord.ConditionsRecordCollection;
+import org.hps.conditions.api.DatabaseObjectException;
+import org.hps.conditions.api.TableMetaData;
 import org.lcsim.conditions.ConditionsManager;
 
 /**
  * Read {@link org.hps.conditions.api.ConditionsRecord} objects from the conditions database.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public final class ConditionsRecordConverter extends AbstractConditionsObjectConverter<ConditionsRecordCollection> {
 
@@ -22,7 +27,8 @@
      * @param name The name of the conditions set.
      * @return The matching ConditionsRecords.
      */
-    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @Override
+    @SuppressWarnings({"unchecked", "rawtypes"})
     public ConditionsRecordCollection getData(final ConditionsManager manager, final String name) {
 
         final DatabaseConditionsManager databaseConditionsManager = DatabaseConditionsManager.getInstance();
@@ -46,7 +52,7 @@
         final ResultSet resultSet = databaseConditionsManager.selectQuery(query);
 
         // Create a collection to return.
-        BaseConditionsObjectCollection collection;
+        ConditionsObjectCollection collection;
         try {
             collection = tableMetaData.getCollectionClass().newInstance();
         } catch (InstantiationException | IllegalAccessException e) {
@@ -55,12 +61,18 @@
 
         try {
             while (resultSet.next()) {
-                final ConditionsObject conditionsRecord = AbstractConditionsObjectConverter.createConditionsObject(resultSet,
-                        tableMetaData);
-                collection.add(conditionsRecord);
+                final ConditionsObject conditionsRecord = new ConditionsRecord();
+                conditionsRecord.setConnection(databaseConditionsManager.getConnection());
+                conditionsRecord.setTableMetaData(tableMetaData);
+                conditionsRecord.select(resultSet.getInt(1));
+                try {
+                    collection.add(conditionsRecord);
+                } catch (final ConditionsObjectException e) {
+                    throw new RuntimeException(e);
+                }
             }
-        } catch (SQLException x) {
-            throw new RuntimeException("Database error", x);
+        } catch (final DatabaseObjectException | SQLException e) {
+            throw new RuntimeException("Error creating new conditions record.", e);
         }
 
         // Close the ResultSet and Statement.
@@ -70,14 +82,15 @@
             databaseConditionsManager.closeConnection();
         }
 
-        return getType().cast(collection);
+        return this.getType().cast(collection);
     }
 
     /**
      * Get the type handled by this converter.
-     * 
+     *
      * @return The type handled by this converter, which is <code>ConditionsRecordCollection</code>.
      */
+    @Override
     public Class<ConditionsRecordCollection> getType() {
         return ConditionsRecordCollection.class;
     }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsSeriesConverter.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsSeriesConverter.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/database/ConditionsSeriesConverter.java	Wed Jul  8 14:47:40 2015
@@ -1,33 +1,35 @@
 package org.hps.conditions.database;
 
-import java.sql.ResultSet;
 import java.sql.SQLException;
 
 import org.hps.conditions.api.ConditionsObject;
 import org.hps.conditions.api.ConditionsObjectCollection;
-import org.hps.conditions.api.ConditionsObjectException;
 import org.hps.conditions.api.ConditionsRecord;
 import org.hps.conditions.api.ConditionsRecord.ConditionsRecordCollection;
 import org.hps.conditions.api.ConditionsSeries;
+import org.hps.conditions.api.DatabaseObjectException;
+import org.hps.conditions.api.TableMetaData;
 
 /**
  * This converter creates a {@link org.hps.conditions.api.ConditionsSeries} which is a list of
- * {@link org.hps.conditions.api.ConditionsObjectCollection} objects having the same type.
- * This can be used to retrieve sets of conditions that may overlap in time validity.  The user
- * may then use whichever collections are of interest to them.
+ * {@link org.hps.conditions.api.ConditionsObjectCollection} objects having the same type. This can be used to retrieve
+ * sets of conditions that may overlap in time validity. The user may then use whichever collections are of interest to
+ * them.
  *
+ * @author Jeremy McCormick, SLAC
  * @see org.hps.conditions.api.ConditionsSeries
  * @see org.hps.conditions.api.ConditionsObjectCollection
  * @see org.hps.conditions.api.ConditionsObject
  * @see DatabaseConditionsManager
- *
  * @param <ObjectType> The type of the ConditionsObject.
  * @param <CollectionType> The type of the collection.
- *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
  */
-final class ConditionsSeriesConverter<ObjectType extends ConditionsObject, 
-    CollectionType extends ConditionsObjectCollection<ObjectType>> {
+final class ConditionsSeriesConverter<ObjectType extends ConditionsObject, CollectionType extends ConditionsObjectCollection<ObjectType>> {
+
+    /**
+     * The type of the collection.
+     */
+    final Class<CollectionType> collectionType;
 
     /**
      * The type of the object.
@@ -35,12 +37,8 @@
     final Class<ObjectType> objectType;
 
     /**
-     * The type of the collection.
-     */
-    final Class<CollectionType> collectionType;
-
-    /**
      * Class constructor.
+     *
      * @param objectType the type of the object
      * @param collectionType the type of the collection
      */
@@ -51,10 +49,11 @@
 
     /**
      * Create a new conditions series.
+     *
      * @param tableName the name of the data table
      * @return the conditions series
      */
-    @SuppressWarnings({ "unchecked" })
+    @SuppressWarnings({"unchecked"})
     final ConditionsSeries<ObjectType, CollectionType> createSeries(final String tableName) {
 
         if (tableName == null) {
@@ -73,53 +72,31 @@
         // Get the table meta data for the collection type.
         final TableMetaData tableMetaData = conditionsManager.findTableMetaData(tableName);
         if (tableMetaData == null) {
-            throw new RuntimeException("Table meta data for " + collectionType + " was not found.");
+            throw new RuntimeException("Table meta data for " + this.collectionType + " was not found.");
         }
 
         // Create a new conditions series.
-        final ConditionsSeries<ObjectType, CollectionType> series =
-                new ConditionsSeries<ObjectType, CollectionType>();
+        final ConditionsSeries<ObjectType, CollectionType> series = new ConditionsSeries<ObjectType, CollectionType>();
 
         // Get the ConditionsRecord with the meta-data, which will use the current run number from the manager.
         final ConditionsRecordCollection conditionsRecords = conditionsManager.findConditionsRecords(tableName);
 
-        for (ConditionsRecord conditionsRecord : conditionsRecords) {
+        for (final ConditionsRecord conditionsRecord : conditionsRecords) {
 
-            ConditionsObjectCollection<ObjectType> collection;
+            ConditionsObjectCollection<?> collection = null;
             try {
-                collection = (ConditionsObjectCollection<ObjectType>)
-                        ConditionsRecordConverter.createCollection(conditionsRecord, tableMetaData);
-            } catch (ConditionsObjectException e) {
+                collection = tableMetaData.getCollectionClass().newInstance();
+            } catch (InstantiationException | IllegalAccessException e1) {
+                throw new RuntimeException(e1);
+            }
+            try {
+                collection.setTableMetaData(tableMetaData);
+                collection.setConnection(conditionsManager.getConnection());
+                collection.select(conditionsRecord.getCollectionId());
+            } catch (final DatabaseObjectException | SQLException e) {
                 throw new RuntimeException(e);
             }
-
-            // Get the collection ID.
-            final int collectionId = conditionsRecord.getCollectionId();
-
-            // Build a select query.
-            final String query = QueryBuilder.buildSelect(tableName, collectionId,
-                    tableMetaData.getFieldNames(), "id ASC");
-
-            // Query the database.
-            final ResultSet resultSet = conditionsManager.selectQuery(query);
-
-            try {
-                // Loop over rows.
-                while (resultSet.next()) {
-                    // Create new ConditionsObject.
-                    final ConditionsObject newObject =
-                            ConditionsRecordConverter.createConditionsObject(resultSet, tableMetaData);
-
-                    // Add new object to collection.
-                    collection.add((ObjectType) newObject);
-                }
-            } catch (SQLException e) {
-                throw new RuntimeException(e);
-            }
-
-            DatabaseUtilities.cleanup(resultSet);
-
-            series.add((CollectionType) collection);
+            series.add((ConditionsObjectCollection<ObjectType>) collection);
         }
 
         if (reopenedConnection) {

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/database/ConnectionParameters.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/database/ConnectionParameters.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/database/ConnectionParameters.java	Wed Jul  8 14:47:40 2015
@@ -13,7 +13,7 @@
 /**
  * This class encapsulates the parameters for connecting to a database, including host name, port, user and password.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public final class ConnectionParameters {
 
@@ -145,13 +145,13 @@
      * @return the new <code>Connection</code> object
      */
     public Connection createConnection() {
-        final Properties connectionProperties = getConnectionProperties();
+        final Properties connectionProperties = this.getConnectionProperties();
         Connection connection = null;
         try {
-            connection = DriverManager.getConnection(getConnectionString(), connectionProperties);
-            connection.createStatement().execute("USE " + getDatabase());
+            connection = DriverManager.getConnection(this.getConnectionString(), connectionProperties);
+            connection.createStatement().execute("USE " + this.getDatabase());
         } catch (final SQLException x) {
-            throw new RuntimeException("Failed to connect to database: " + getConnectionString(), x);
+            throw new RuntimeException("Failed to connect to database: " + this.getConnectionString(), x);
         }
         return connection;
     }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/database/Converter.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/database/Converter.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/database/Converter.java	Wed Jul  8 14:47:40 2015
@@ -5,28 +5,30 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.hps.conditions.api.AbstractConditionsObjectConverter;
+
 /**
  * This is an annotation for providing converter configuration for {@link org.hps.conditions.api.ConditionsObject}
  * classes.
  *
  * @see AbstractConditionsObjectConverter
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
 public @interface Converter {
+    /**
+     * Get a custom converter class for the type. (Optional)
+     *
+     * @return the custom converter for the type
+     */
+    Class<?> converter() default AbstractConditionsObjectConverter.class;
+
     /**
      * Get the action to perform in the converter when multiple conditions are found for the current configuration of
      * run number, detector and tag in the manager.
      *
      * @return the multiple collections action
      */
-    MultipleCollectionsAction multipleCollectionsAction() default MultipleCollectionsAction.ERROR;
-
-    /**
-     * Get a custom converter class for the type. (Optional)
-     *
-     * @return the custom converter for the type
-     */
-    Class<?> converter() default AbstractConditionsObjectConverter.class;
+    MultipleCollectionsAction multipleCollectionsAction() default MultipleCollectionsAction.LAST_CREATED;
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/database/ConverterRegistry.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/database/ConverterRegistry.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/database/ConverterRegistry.java	Wed Jul  8 14:47:40 2015
@@ -6,9 +6,10 @@
 
 import javassist.Modifier;
 
+import org.hps.conditions.api.AbstractConditionsObjectConverter;
 import org.hps.conditions.api.BaseConditionsObjectCollection;
 import org.hps.conditions.api.ConditionsObject;
-import org.hps.conditions.api.ConditionsObjectUtilities;
+import org.hps.conditions.api.TableRegistry;
 import org.reflections.Reflections;
 
 /**
@@ -18,50 +19,51 @@
  * instantiate the specific converter class instead.
  *
  * @see AbstractConditionsObjectConverter
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 @SuppressWarnings("serial")
-public final class ConverterRegistry extends HashMap<Class<? extends ConditionsObject>, AbstractConditionsObjectConverter> {
-
-    /**
-     * Class should not be instantiated by users.
-     * The {@link #create()} method should be used instead.
-     */
-    private ConverterRegistry() {
-    }
+public final class ConverterRegistry extends
+        HashMap<Class<? extends ConditionsObject>, AbstractConditionsObjectConverter> {
 
     /**
      * Automatically create converters for all {@link org.hps.conditions.api.ConditionsObject} classes.
-     * 
+     *
      * @return the global registry of converters
      */
-    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @SuppressWarnings({"unchecked", "rawtypes"})
     static ConverterRegistry create() {
         final ConverterRegistry registry = new ConverterRegistry();
         final Reflections reflections = new Reflections("org.hps.conditions");
         final Set<Class<? extends ConditionsObject>> objectTypes = reflections.getSubTypesOf(ConditionsObject.class);
-        for (Class<? extends ConditionsObject> objectType : objectTypes) {
+        for (final Class<? extends ConditionsObject> objectType : objectTypes) {
             if (Modifier.isAbstract(objectType.getModifiers())) {
+                // Abstract classes are not mapped to the db.
                 continue;
             }
             if (objectType.getAnnotation(Table.class) == null) {
+                // Explicit table mapping is required.
                 continue;
             }
-            MultipleCollectionsAction multipleCollectionsAction = MultipleCollectionsAction.ERROR;
+
+            // Class of the converter.
             Class<?> converterClass = null;
+
+            // Annotation for converter parameters (optional).
             final Converter converterAnnotation = objectType.getAnnotation(Converter.class);
             if (converterAnnotation != null) {
-                multipleCollectionsAction = converterAnnotation.multipleCollectionsAction();
                 if (!converterAnnotation.converter().equals(AbstractConditionsObjectConverter.class)) {
+                    // Set class of converter from annotation (usually default is fine).
                     converterClass = converterAnnotation.converter();
                 }
             }
 
-            final Class<? extends BaseConditionsObjectCollection<? extends ConditionsObject>> 
-                collectionType = ConditionsObjectUtilities.getCollectionType(objectType);
+            // Type of the collection.
+            final Class<? extends BaseConditionsObjectCollection<? extends ConditionsObject>> collectionType = TableRegistry
+                    .getCollectionType(objectType);
 
             AbstractConditionsObjectConverter converter = null;
             if (converterClass == null) {
+                // Create a generic/anonymous converter.
                 converter = new AbstractConditionsObjectConverter() {
                     @Override
                     public Class getType() {
@@ -69,8 +71,9 @@
                     }
                 };
             } else {
+                // Create a converter instance from the provided type in the annotation.
                 try {
-                    Object object = converterClass.newInstance();
+                    final Object object = converterClass.newInstance();
                     if (!(object instanceof AbstractConditionsObjectConverter)) {
                         throw new RuntimeException("The Converter has the wrong type: "
                                 + object.getClass().getCanonicalName());
@@ -80,20 +83,34 @@
                     throw new RuntimeException(e);
                 }
             }
-            converter.setMultipleCollectionsAction(multipleCollectionsAction);
+
+            // Set the converter's strategy for disambiguating overlapping time validity.
+            if (converterAnnotation != null && converterAnnotation.multipleCollectionsAction() != null) {
+                converter.setMultipleCollectionsAction(converterAnnotation.multipleCollectionsAction());
+            }
+
+            // Register the converter by its conversion type.
             registry.put(converter.getType(), converter);
         }
         return registry;
     }
 
     /**
+     * Class should not be instantiated by users. The {@link #create()} method should be used instead.
+     */
+    private ConverterRegistry() {
+    }
+
+    /**
      * Convert the object to a string.
+     *
      * @return the object converted to a string
      */
+    @Override
     @SuppressWarnings("rawtypes")
     public String toString() {
         final StringBuffer buff = new StringBuffer();
-        for (Entry<Class<? extends ConditionsObject>, AbstractConditionsObjectConverter> entry : entrySet()) {
+        for (final Entry<Class<? extends ConditionsObject>, AbstractConditionsObjectConverter> entry : this.entrySet()) {
             buff.append(entry.getValue().toString());
         }
         return buff.toString();

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java	Wed Jul  8 14:47:40 2015
@@ -14,17 +14,19 @@
 import java.util.ArrayList;
 import java.util.LinkedHashSet;
 import java.util.List;
-import java.util.Map.Entry;
 import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.hps.conditions.api.AbstractConditionsObjectConverter;
 import org.hps.conditions.api.ConditionsObject;
 import org.hps.conditions.api.ConditionsObjectCollection;
 import org.hps.conditions.api.ConditionsObjectException;
 import org.hps.conditions.api.ConditionsRecord;
 import org.hps.conditions.api.ConditionsRecord.ConditionsRecordCollection;
 import org.hps.conditions.api.ConditionsSeries;
+import org.hps.conditions.api.TableMetaData;
+import org.hps.conditions.api.TableRegistry;
 import org.hps.conditions.ecal.EcalConditions;
 import org.hps.conditions.ecal.EcalConditionsConverter;
 import org.hps.conditions.ecal.TestRunEcalConditionsConverter;
@@ -54,7 +56,7 @@
  * Differences between Test Run and Engineering Run configurations are handled automatically.
  *
  * @see org.lcsim.conditions.ConditionsManager
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 @SuppressWarnings("rawtypes")
 public final class DatabaseConditionsManager extends ConditionsManagerImplementation {
@@ -254,7 +256,7 @@
     /**
      * Create the global registry of table meta data.
      */
-    private final TableRegistry tableRegistry = TableRegistry.create();
+    private final TableRegistry tableRegistry = TableRegistry.getTableRegistry();
 
     /**
      * The currently active conditions tag.
@@ -274,54 +276,6 @@
             this.registerConditionsConverter(converter);
         }
         this.addConditionsListener(this.svtSetup);
-    }
-
-    /**
-     * Add a row for a new collection and return the new collection ID assigned to it.
-     *
-     * @param tableName the name of the table
-     * @param comment an optional comment about this new collection
-     * @return the collection's ID
-     * @throws SQLException
-     */
-    public synchronized int addCollection(final String tableName, final String log, final String description)
-            throws SQLException {
-        if (tableName == null) {
-            throw new IllegalArgumentException("The tableName argument is null.");
-        }
-        final boolean opened = this.openConnection();
-        PreparedStatement statement = null;
-        ResultSet resultSet = null;
-        int collectionId = -1;
-        try {
-            statement = this.connection.prepareStatement(
-                    "INSERT INTO collections (table_name, log, description, created) VALUES (?, ?, ?, NOW())",
-                    Statement.RETURN_GENERATED_KEYS);
-            statement.setString(1, tableName);
-            if (log == null) {
-                statement.setNull(2, java.sql.Types.VARCHAR);
-            } else {
-                statement.setString(2, log);
-            }
-            if (description == null) {
-                statement.setNull(3, java.sql.Types.VARCHAR);
-            } else {
-                statement.setString(3, description);
-            }
-            statement.execute();
-            resultSet = statement.getGeneratedKeys();
-            resultSet.next();
-            collectionId = resultSet.getInt(1);
-        } finally {
-            if (resultSet != null) {
-                resultSet.close();
-            }
-            if (statement != null) {
-                statement.close();
-            }
-            this.closeConnection(opened);
-        }
-        return collectionId;
     }
 
     /**
@@ -355,7 +309,7 @@
         }
         this.connection = null;
         this.isConnected = false;
-        logger.info("connection closed");
+        logger.fine("connection closed");
     }
 
     /**
@@ -435,7 +389,11 @@
         for (final ConditionsRecord record : runConditionsRecords) {
             if (record.getName().equals(name)) {
                 if (this.matchesTag(record)) {
-                    foundConditionsRecords.add(record);
+                    try {
+                        foundConditionsRecords.add(record);
+                    } catch (final ConditionsObjectException e) {
+                        throw new RuntimeException(e);
+                    }
                     logger.finer("found matching conditions record " + record.getRowId());
                 } else {
                     logger.finer("conditions record " + record.getRowId() + " rejected from non-matching tag "
@@ -478,6 +436,52 @@
         } else {
             logger.warning("conditions system cannot be frozen because it is not initialized yet");
         }
+    }
+
+    /**
+     * Add a row for a new collection and return the new collection ID assigned to it.
+     *
+     * @param tableName the name of the table
+     * @param comment an optional comment about this new collection
+     * @return the collection's ID
+     * @throws SQLException
+     */
+    public synchronized int getCollectionId(final ConditionsObjectCollection<?> collection, final String description)
+            throws SQLException {
+
+        final String caller = Thread.currentThread().getStackTrace()[2].getClassName();
+        final String log = "created by " + System.getProperty("user.name") + " using "
+                + caller.substring(caller.lastIndexOf('.') + 1);
+        final boolean opened = this.openConnection();
+        PreparedStatement statement = null;
+        ResultSet resultSet = null;
+        int collectionId = -1;
+        try {
+            statement = this.connection.prepareStatement(
+                    "INSERT INTO collections (table_name, log, description, created) VALUES (?, ?, ?, NOW())",
+                    Statement.RETURN_GENERATED_KEYS);
+            statement.setString(1, collection.getTableMetaData().getTableName());
+            statement.setString(2, log);
+            if (description == null) {
+                statement.setNull(3, java.sql.Types.VARCHAR);
+            } else {
+                statement.setString(3, description);
+            }
+            statement.execute();
+            resultSet = statement.getGeneratedKeys();
+            resultSet.next();
+            collectionId = resultSet.getInt(1);
+        } finally {
+            if (resultSet != null) {
+                resultSet.close();
+            }
+            if (statement != null) {
+                statement.close();
+            }
+            this.closeConnection(opened);
+        }
+        collection.setCollectionId(collectionId);
+        return collectionId;
     }
 
     /**
@@ -534,6 +538,18 @@
     }
 
     /**
+     * Get the JDBC connection.
+     *
+     * @return the JDBC connection
+     */
+    public Connection getConnection() {
+        if (!this.isConnected()) {
+            this.openConnection();
+        }
+        return this.connection;
+    }
+
+    /**
      * Get the current LCSim compact <code>Detector</code> object with the geometry and detector model.
      *
      * @return the detector object
@@ -619,7 +635,7 @@
      * @return <code>true</code> if a conditions record exists with the given name
      */
     public boolean hasConditionsRecord(final String name) {
-        return !this.findConditionsRecords(name).isEmpty();
+        return this.findConditionsRecords(name).size() != 0;
     }
 
     /**
@@ -693,90 +709,6 @@
     }
 
     /**
-     * Insert a collection of ConditionsObjects into the database.
-     *
-     * @param collection the collection to insert
-     * @param <ObjectType> the type of the conditions object
-     * @throws SQLException if there is a database or SQL error
-     * @throws ConditionsObjectException if there is a problem inserting the object
-     */
-    public <ObjectType extends ConditionsObject> void insertCollection(
-            final ConditionsObjectCollection<ObjectType> collection) throws SQLException, ConditionsObjectException {
-
-        if (collection == null) {
-            throw new IllegalArgumentException("The collection is null.");
-        }
-        if (collection.size() == 0) {
-            throw new IllegalArgumentException("The collection is empty.");
-        }
-
-        TableMetaData tableMetaData = collection.getTableMetaData();
-        if (tableMetaData == null) {
-            final List<TableMetaData> metaDataList = this.tableRegistry.findByCollectionType(collection.getClass());
-            if (metaDataList == null) {
-                // This is a fatal error because no meta data is available for the type.
-                throw new ConditionsObjectException("Failed to find meta data for type: " + collection.getClass());
-            }
-            tableMetaData = metaDataList.get(0);
-        }
-        if (collection.getCollectionId() == -1) {
-            try {
-                collection.setCollectionId(this.addCollection(tableMetaData.getTableName(),
-                        "DatabaseConditionsManager created collection by " + System.getProperty("user.name"), null));
-            } catch (final ConditionsObjectException e) {
-                throw new RuntimeException(e);
-            }
-        }
-        // FIXME: If collection ID is already set this should be an error!
-
-        logger.info("inserting collection with ID " + collection.getCollectionId() + " and key "
-                + tableMetaData.getKey() + " into table " + tableMetaData.getTableName());
-
-        final boolean openedConnection = this.openConnection();
-
-        PreparedStatement preparedStatement = null;
-
-        try {
-            this.connection.setAutoCommit(false);
-            logger.fine("starting insert transaction");
-            final String sql = QueryBuilder.buildPreparedInsert(tableMetaData.getTableName(), collection.iterator()
-                    .next());
-            preparedStatement = this.connection.prepareStatement(sql);
-            logger.fine("using prepared statement: " + sql);
-            final int collectionId = collection.getCollectionId();
-            for (final ConditionsObject object : collection) {
-                preparedStatement.setObject(1, collectionId);
-                int parameterIndex = 2;
-                if (object instanceof ConditionsRecord) {
-                    parameterIndex = 1;
-                }
-                for (final Entry<String, Object> entry : object.getFieldValues().entrySet()) {
-                    preparedStatement.setObject(parameterIndex, entry.getValue());
-                    ++parameterIndex;
-                }
-                preparedStatement.executeUpdate();
-            }
-            this.connection.commit();
-            logger.fine("committed transaction");
-        } catch (final Exception e) {
-            e.printStackTrace();
-            logger.warning(e.getMessage());
-            logger.warning("rolling back transaction");
-            this.connection.rollback();
-            logger.warning("transaction was rolled back");
-        } finally {
-            this.connection.setAutoCommit(true);
-        }
-
-        try {
-            preparedStatement.close();
-        } catch (final Exception e) {
-        }
-
-        this.closeConnection(openedConnection);
-    }
-
-    /**
      * Check if connected to the database.
      *
      * @return <code>true</code> if connected
@@ -895,6 +827,40 @@
             return false;
         }
         return this.tag.equals(recordTag);
+    }
+
+    public <CollectionType extends ConditionsObjectCollection<?>> CollectionType newCollection(
+            final Class<CollectionType> collectionType) {
+        final List<TableMetaData> tableMetaDataList = TableRegistry.getTableRegistry().findByCollectionType(
+                collectionType);
+        if (tableMetaDataList.size() > 1) {
+            throw new RuntimeException("More than one table meta data object returned for type: "
+                    + collectionType.getName());
+        }
+        final TableMetaData tableMetaData = tableMetaDataList.get(0);
+        CollectionType collection;
+        try {
+            collection = collectionType.newInstance();
+        } catch (InstantiationException | IllegalAccessException e) {
+            throw new RuntimeException("Error creating new collection.", e);
+        }
+        collection.setTableMetaData(tableMetaData);
+        collection.setConnection(this.getConnection());
+        return collection;
+    }
+
+    public <CollectionType extends ConditionsObjectCollection<?>> CollectionType newCollection(
+            final Class<CollectionType> collectionType, final String tableName) {
+        final TableMetaData tableMetaData = TableRegistry.getTableRegistry().findByTableName(tableName);
+        CollectionType collection;
+        try {
+            collection = collectionType.newInstance();
+        } catch (InstantiationException | IllegalAccessException e) {
+            throw new RuntimeException("Error creating new collection.", e);
+        }
+        collection.setTableMetaData(tableMetaData);
+        collection.setConnection(this.getConnection());
+        return collection;
     }
 
     /**
@@ -926,7 +892,7 @@
             this.isConnected = true;
             openedConnection = true;
         }
-        logger.info("connection opened successfully");
+        logger.fine("connection opened successfully");
 
         // Flag to indicate whether an existing connection was used or not.
         return openedConnection;

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/database/DatabaseUtilities.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/database/DatabaseUtilities.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/database/DatabaseUtilities.java	Wed Jul  8 14:47:40 2015
@@ -6,16 +6,10 @@
 /**
  * Database utility methods.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 // TODO: Merge this single method into the manager class or a connection utilities class.
 public final class DatabaseUtilities {
-
-    /**
-     * Do not allow instantiation.
-     */
-    private DatabaseUtilities() {
-    }
 
     /**
      * Cleanup a JDBC <code>ResultSet</code> by closing it and its <code>Statement</code>
@@ -26,22 +20,28 @@
         Statement statement = null;
         try {
             statement = resultSet.getStatement();
-        } catch (Exception e) {
+        } catch (final Exception e) {
         }
         try {
             if (resultSet != null) {
                 resultSet.close();
             }
-        } catch (Exception e) {
+        } catch (final Exception e) {
             e.printStackTrace();
         }
         try {
             if (statement != null) {
                 statement.close();
             }
-        } catch (Exception e) {
+        } catch (final Exception e) {
             e.printStackTrace();
         }
     }
 
+    /**
+     * Do not allow instantiation.
+     */
+    private DatabaseUtilities() {
+    }
+
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/database/Field.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/database/Field.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/database/Field.java	Wed Jul  8 14:47:40 2015
@@ -6,16 +6,17 @@
 import java.lang.annotation.Target;
 
 /**
- * This is a java <code>Annotation</code> for assigning a "get" method
- * to one or more database table columns.
+ * This is a java <code>Annotation</code> for assigning a "get" method to one or more database table columns.
+ * 
+ * @author Jeremy McCormick, SLAC
  */
 @Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD) 
+@Target(ElementType.METHOD)
 public @interface Field {
 
     /**
      * The names of the table columns associated with this method.
-     * 
+     *
      * @return the names of the table columns associated with this method
      */
     String[] names() default "";

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/database/MultipleCollectionsAction.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/database/MultipleCollectionsAction.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/database/MultipleCollectionsAction.java	Wed Jul  8 14:47:40 2015
@@ -1,27 +1,26 @@
 package org.hps.conditions.database;
 
 /**
- * This is the action that should be used to pick a conditions set
- * if there are multiple conditions sets returned from a query on
- * type and name.
+ * This is the action that should be used to pick a conditions set if there are multiple conditions sets returned from a
+ * query on type and name.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public enum MultipleCollectionsAction {
+    /**
+     * Throw an error.
+     */
+    ERROR,
+    /**
+     * Use the creation date.
+     */
+    LAST_CREATED,
     /**
      * Use the updated date.
      */
     LAST_UPDATED,
     /**
-     * Use the creation date.
-     */
-    LAST_CREATED,
-    /**
      * Use the largest run start number.
      */
-    LATEST_RUN_START,
-    /**
-     * Throw an error.
-     */
-    ERROR
+    LATEST_RUN_START
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/database/Table.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/database/Table.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/database/Table.java	Wed Jul  8 14:47:40 2015
@@ -6,17 +6,17 @@
 import java.lang.annotation.Target;
 
 /**
- * This annotation can be used to assign a class to one
- * or more database tables.
+ * This annotation can be used to assign a class to one or more database tables.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 @Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE) 
+@Target(ElementType.TYPE)
 public @interface Table {
 
     /**
      * Get the names of the tables.
+     *
      * @return the names of the tables
      */
     String[] names() default "";

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/database/package-info.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/database/package-info.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/database/package-info.java	Wed Jul  8 14:47:40 2015
@@ -1,12 +1,12 @@
 /**
- * This package contains classes for converting database information
- * into conditions classes as well as updating the records from the
- * objects.
+ * This package contains classes for converting database information into conditions classes as well as updating the
+ * records from the objects.
  *
+ * @author Jeremy McCormick, SLAC
  * @see DatabaseConditionsManager
  * @see TableMetaData
  * @see AbstractConditionsObjectConverter
  * @see ConditionsSeriesConverter
- * @author Jeremy McCormick <[log in to unmask]>
  */
 package org.hps.conditions.database;
+

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalBadChannel.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalBadChannel.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalBadChannel.java	Wed Jul  8 14:47:40 2015
@@ -4,17 +4,16 @@
 
 import org.hps.conditions.api.BaseConditionsObject;
 import org.hps.conditions.api.BaseConditionsObjectCollection;
-import org.hps.conditions.database.Converter;
+import org.hps.conditions.api.ConditionsObjectCollection;
 import org.hps.conditions.database.Field;
-import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
 
 /**
- * This class represents an ECAL channel that is considered "bad" which means it
- * should not be used in reconstruction.
+ * This class represents an ECAL channel that is considered "bad" which means it should not be used in reconstruction.
+ * 
+ * @author Jeremy McCormick, SLAC
  */
 @Table(names = {"ecal_bad_channels", "test_run_ecal_bad_channels"})
-@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_UPDATED)
 public final class EcalBadChannel extends BaseConditionsObject {
 
     /**
@@ -22,26 +21,20 @@
      */
     @SuppressWarnings("serial")
     public static class EcalBadChannelCollection extends BaseConditionsObjectCollection<EcalBadChannel> {
-        
-        /**
-         * Sort and return the collection without modifying in place.
-         * @return the sorted collection
-         */
-        public BaseConditionsObjectCollection<EcalBadChannel> sorted() {
-            return sorted(new ChannelIdComparator());
-        }
-                
+
         /**
          * Comparison class for ECAL bad channels, which uses channel ID.
          */
         class ChannelIdComparator implements Comparator<EcalBadChannel> {
             /**
              * Compare two ECAL bad channel objects.
+             *
              * @param o1 the first object
              * @param o2 the second object
              * @return -1, 0, 1 if first channel ID is less than, equal to, or greater than the second
              */
-            public int compare(EcalBadChannel o1, EcalBadChannel o2) {
+            @Override
+            public int compare(final EcalBadChannel o1, final EcalBadChannel o2) {
                 if (o1.getChannelId() < o2.getChannelId()) {
                     return -1;
                 } else if (o1.getChannelId() > o2.getChannelId()) {
@@ -51,14 +44,24 @@
                 }
             }
         }
+
+        /**
+         * Sort and return the collection without modifying in place.
+         *
+         * @return the sorted collection
+         */
+        public ConditionsObjectCollection<EcalBadChannel> sorted() {
+            return this.sorted(new ChannelIdComparator());
+        }
     }
 
     /**
      * Get the ECAL channel ID.
+     *
      * @return the ECAL channel ID
      */
     @Field(names = {"ecal_channel_id"})
-    public int getChannelId() {
-        return getFieldValue("ecal_channel_id");
+    public Integer getChannelId() {
+        return this.getFieldValue("ecal_channel_id");
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalCalibration.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalCalibration.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalCalibration.java	Wed Jul  8 14:47:40 2015
@@ -4,37 +4,23 @@
 
 import org.hps.conditions.api.BaseConditionsObject;
 import org.hps.conditions.api.BaseConditionsObjectCollection;
-import org.hps.conditions.database.Converter;
+import org.hps.conditions.api.ConditionsObjectCollection;
 import org.hps.conditions.database.Field;
-import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
 
 /**
- * This class is a simplistic representation of ECal pedestal and noise values
- * from the conditions database.
+ * This class represents ECal pedestal and noise values from the conditions database. The pedestal and noise are in
+ * units of ADC counts. They are the mean and the standard deviation of the digitized pre-amp output.
  *
- * The pedestal and noise are in units of ADC counts. They are the mean and the
- * standard deviation of the digitized pre-amp output.
- *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
-@Table(names = {"ecal_calibrations", "test_run_ecal_calibrations", "ecal_hardware_calibrations"})
-@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED)
+@Table(names = {"ecal_calibrations", "test_run_ecal_calibrations"})
 public final class EcalCalibration extends BaseConditionsObject {
 
     /**
      * The collection implementation for the object class.
      */
-    @SuppressWarnings("serial")
     public static class EcalCalibrationCollection extends BaseConditionsObjectCollection<EcalCalibration> {
-
-        /**
-         * Sort and return the collection but do no modify in place.
-         * @return the sorted collection
-         */
-        public BaseConditionsObjectCollection<EcalCalibration> sorted() {
-            return sorted(new ChannelIdComparator());
-        }
 
         /**
          * Comparison using channel ID.
@@ -42,10 +28,12 @@
         class ChannelIdComparator implements Comparator<EcalCalibration> {
             /**
              * Compare two ECAL calibration objects.
+             *
              * @param o1 the first object
              * @param o2 the second object
              * @return -1, 0, 1 if first channel ID is less than, equal to, or greater than the second
              */
+            @Override
             public int compare(final EcalCalibration o1, final EcalCalibration o2) {
                 if (o1.getChannelId() < o2.getChannelId()) {
                     return -1;
@@ -55,6 +43,15 @@
                     return 0;
                 }
             }
+        }
+
+        /**
+         * Sort and return the collection but do no modify in place.
+         *
+         * @return the sorted collection
+         */
+        public ConditionsObjectCollection<EcalCalibration> sorted() {
+            return this.sorted(new ChannelIdComparator());
         }
     }
 
@@ -66,6 +63,7 @@
 
     /**
      * Full qualified constructor.
+     *
      * @param channelId the channel ID
      * @param pedestal the pedestal measurement (ADC counts)
      * @param noise the noise measured as RMS
@@ -78,30 +76,31 @@
 
     /**
      * Get the ECAL channel ID.
+     *
      * @return the ECAL channel ID
      */
     @Field(names = {"ecal_channel_id"})
-    public int getChannelId() {
-        return getFieldValue("ecal_channel_id");
+    public Integer getChannelId() {
+        return this.getFieldValue("ecal_channel_id");
     }
 
     /**
-     * Get the pedestal value in units of ADC counts, which is the mean of the
-     * digitized preamplifier output.
+     * Get the noise value in units of ADC counts, which is the standard deviation of the digitized preamplifier output.
+     *
+     * @return the noise value
+     */
+    @Field(names = {"noise"})
+    public Double getNoise() {
+        return this.getFieldValue("noise");
+    }
+
+    /**
+     * Get the pedestal value in units of ADC counts, which is the mean of the digitized preamplifier output.
+     *
      * @return the gain value
      */
     @Field(names = {"pedestal"})
-    public double getPedestal() {
-        return getFieldValue("pedestal");
-    }
-
-    /**
-     * Get the noise value in units of ADC counts, which is the standard
-     * deviation of the digitized preamplifier output.
-     * @return the noise value
-     */
-    @Field(names = {"noise"})
-    public double getNoise() {
-        return getFieldValue("noise");
+    public Double getPedestal() {
+        return this.getFieldValue("pedestal");
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalChannel.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalChannel.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalChannel.java	Wed Jul  8 14:47:40 2015
@@ -4,14 +4,15 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import org.hps.conditions.api.AbstractConditionsObjectConverter;
 import org.hps.conditions.api.AbstractIdentifier;
 import org.hps.conditions.api.BaseConditionsObject;
 import org.hps.conditions.api.BaseConditionsObjectCollection;
-import org.hps.conditions.database.AbstractConditionsObjectConverter;
+import org.hps.conditions.api.ConditionsObjectCollection;
+import org.hps.conditions.api.ConditionsObjectException;
 import org.hps.conditions.database.Converter;
 import org.hps.conditions.database.DatabaseConditionsManager;
 import org.hps.conditions.database.Field;
-import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
 import org.lcsim.conditions.ConditionsManager;
 import org.lcsim.detector.identifier.ExpandedIdentifier;
@@ -23,10 +24,10 @@
  * This class encapsulates all the information about a single ECal channel, corresponding to one physical crystal in the
  * detector.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 @Table(names = {"ecal_channels", "test_run_ecal_channels"})
-@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED, converter = EcalChannel.EcalChannelConverter.class)
+@Converter(converter = EcalChannel.EcalChannelConverter.class)
 public final class EcalChannel extends BaseConditionsObject {
 
     /**
@@ -177,7 +178,7 @@
          * @return <code>true</code> if object was added successfully
          */
         @Override
-        public boolean add(final EcalChannel channel) {
+        public boolean add(final EcalChannel channel) throws ConditionsObjectException {
             super.add(channel);
             final DaqId daqId = channel.createDaqId();
             if (daqId.isValid()) {
@@ -268,9 +269,8 @@
          *
          * @return the sorted copy of the collection
          */
-        @Override
-        public BaseConditionsObjectCollection<EcalChannel> sorted() {
-            return sorted(new ChannelIdComparator());
+        public ConditionsObjectCollection<EcalChannel> sorted() {
+            return this.sorted(new ChannelIdComparator());
         }
     }
 
@@ -387,7 +387,7 @@
      * @return the {@link #DaqId} for this ECAL channel
      */
     DaqId createDaqId() {
-        return new DaqId(new int[] {getCrate(), getSlot(), getChannel()});
+        return new DaqId(new int[] {this.getCrate(), this.getSlot(), this.getChannel()});
     }
 
     /**
@@ -398,7 +398,7 @@
      * @return the geometry ID
      */
     GeometryId createGeometryId(final IIdentifierHelper helper, final int system) {
-        return new GeometryId(helper, new int[] {system, getX(), getY()});
+        return new GeometryId(helper, new int[] {system, this.getX(), this.getY()});
     }
 
     /**
@@ -419,8 +419,9 @@
             return true;
         }
         final EcalChannel c = (EcalChannel) o;
-        return c.getChannelId() == getChannelId() && c.getCrate() == getCrate() && c.getSlot() == getSlot()
-                && c.getChannel() == getChannel() && c.getX() == getX() && c.getY() == getY();
+        return c.getChannelId() == this.getChannelId() && c.getCrate() == this.getCrate()
+                && c.getSlot() == this.getSlot() && c.getChannel() == this.getChannel() && c.getX() == this.getX()
+                && c.getY() == this.getY();
     }
 
     /**
@@ -429,8 +430,8 @@
      * @return the channel number
      */
     @Field(names = {"channel"})
-    public int getChannel() {
-        return getFieldValue("channel");
+    public Integer getChannel() {
+        return this.getFieldValue("channel");
     }
 
     /**
@@ -439,8 +440,8 @@
      * @return the ID of the channel
      */
     @Field(names = {"channel_id"})
-    public int getChannelId() {
-        return getFieldValue("channel_id");
+    public Integer getChannelId() {
+        return this.getFieldValue("channel_id");
     }
 
     /**
@@ -449,8 +450,8 @@
      * @return the crate number
      */
     @Field(names = {"crate"})
-    public int getCrate() {
-        return getFieldValue("crate");
+    public Integer getCrate() {
+        return this.getFieldValue("crate");
     }
 
     /**
@@ -459,8 +460,8 @@
      * @return the slot number
      */
     @Field(names = {"slot"})
-    public int getSlot() {
-        return getFieldValue("slot");
+    public Integer getSlot() {
+        return this.getFieldValue("slot");
     }
 
     /**
@@ -469,8 +470,8 @@
      * @return the x value
      */
     @Field(names = {"x"})
-    public int getX() {
-        return getFieldValue("x");
+    public Integer getX() {
+        return this.getFieldValue("x");
     }
 
     /**
@@ -479,7 +480,7 @@
      * @return the y value
      */
     @Field(names = {"y"})
-    public int getY() {
-        return getFieldValue("y");
+    public Integer getY() {
+        return this.getFieldValue("y");
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalChannelConstants.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalChannelConstants.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalChannelConstants.java	Wed Jul  8 14:47:40 2015
@@ -2,8 +2,8 @@
 
 /**
  * This class represents the conditions of a single ECAL channel such as a calibration and gain.
- * 
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ *
+ * @author Jeremy McCormick, SLAC
  * @see EcalGain
  * @see EcalCalibration
  * @see EcalTimeShift
@@ -12,9 +12,9 @@
 public final class EcalChannelConstants {
 
     /**
-     * The channel {@link EcalGain} conditions.
+     * True if channel is bad and should not be used for reconstruction.
      */
-    private EcalGain gain = null;
+    private boolean badChannel = false;
 
     /**
      * The channel {@link EcalCalibration} conditions.
@@ -22,14 +22,14 @@
     private EcalCalibration calibration = null;
 
     /**
+     * The channel {@link EcalGain} conditions.
+     */
+    private EcalGain gain = null;
+
+    /**
      * The channel {@link EcalTimeShift} conditions.
      */
     private EcalTimeShift timeShift = null;
-
-    /**
-     * True if channel is bad and should not be used for reconstruction.
-     */
-    private boolean badChannel = false;
 
     /**
      * Class constructor, which is package protected.
@@ -38,8 +38,62 @@
     }
 
     /**
+     * Get the calibration.
+     *
+     * @return The calibration.
+     */
+    public EcalCalibration getCalibration() {
+        return this.calibration;
+    }
+
+    /**
+     * Get the gain.
+     *
+     * @return The gain.
+     */
+    public EcalGain getGain() {
+        return this.gain;
+    }
+
+    /**
+     * Get the time shift.
+     *
+     * @return The time shift.
+     */
+    public EcalTimeShift getTimeShift() {
+        return this.timeShift;
+    }
+
+    /**
+     * True if this is a bad channel.
+     *
+     * @return True if channel is bad.
+     */
+    public boolean isBadChannel() {
+        return this.badChannel;
+    }
+
+    /**
+     * Set whether this is a bad channel.
+     *
+     * @param badChannel set to true to flag channel as bad
+     */
+    void setBadChannel(final boolean badChannel) {
+        this.badChannel = badChannel;
+    }
+
+    /**
+     * Set the calibration.
+     *
+     * @param calibration the new calibration object
+     */
+    void setCalibration(final EcalCalibration calibration) {
+        this.calibration = calibration;
+    }
+
+    /**
      * Set the gain.
-     * 
+     *
      * @param gain the new gain object
      */
     void setGain(final EcalGain gain) {
@@ -47,65 +101,11 @@
     }
 
     /**
-     * Set the calibration.
-     * 
-     * @param calibration the new calibration object
-     */
-    void setCalibration(final EcalCalibration calibration) {
-        this.calibration = calibration;
-    }
-
-    /**
      * Set the time shift.
-     * 
+     *
      * @param timeShift the new time shift
      */
     void setTimeShift(final EcalTimeShift timeShift) {
         this.timeShift = timeShift;
     }
-
-    /**
-     * Set whether this is a bad channel.
-     * 
-     * @param badChannel set to true to flag channel as bad
-     */
-    void setBadChannel(final boolean badChannel) {
-        this.badChannel = badChannel;
-    }
-
-    /**
-     * Get the gain.
-     * 
-     * @return The gain.
-     */
-    public EcalGain getGain() {
-        return gain;
-    }
-
-    /**
-     * Get the calibration.
-     * 
-     * @return The calibration.
-     */
-    public EcalCalibration getCalibration() {
-        return calibration;
-    }
-
-    /**
-     * Get the time shift.
-     * 
-     * @return The time shift.
-     */
-    public EcalTimeShift getTimeShift() {
-        return timeShift;
-    }
-
-    /**
-     * True if this is a bad channel.
-     * 
-     * @return True if channel is bad.
-     */
-    public boolean isBadChannel() {
-        return badChannel;
-    }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalConditions.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalConditions.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalConditions.java	Wed Jul  8 14:47:40 2015
@@ -9,17 +9,21 @@
 import org.lcsim.geometry.Subdetector;
 
 /**
- * This class provides access to all ECAL conditions from the database,
- * including gain, pedestal and bad channel settings, per crystal.
+ * This class provides access to all ECAL conditions from the database, including gain, pedestal and bad channel
+ * settings, per crystal.
  * <p>
- * Unlike most conditions data types, it does not extend
- * {@link org.hps.conditions.api.ConditionsObject}, because it is a composite object
- * containing data assembled from many other {@link org.hps.conditions.ConditionsObjects}
- * and has a special data converter {@link EcalConditionsConverter}.
+ * Unlike most conditions data types, it does not extend {@link org.hps.conditions.api.ConditionsObject}, because it is
+ * a composite object containing data assembled from many other {@link org.hps.conditions.ConditionsObjects} and has a
+ * special data converter {@link EcalConditionsConverter}.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public final class EcalConditions {
+
+    /**
+     * This is just used for a divider length in print output.
+     */
+    private static final int DIVIDER_SIZE = 91;
 
     /**
      * The collection of {@link EcalChannel} objects.
@@ -29,8 +33,7 @@
     /**
      * Map between channels and their conditions constants.
      */
-    private final Map<EcalChannel, EcalChannelConstants> channelConstants = 
-            new HashMap<EcalChannel, EcalChannelConstants>();
+    private final Map<EcalChannel, EcalChannelConstants> channelConstants = new HashMap<EcalChannel, EcalChannelConstants>();
 
     /**
      * Map between channels and geometric crystals.
@@ -44,6 +47,7 @@
 
     /**
      * Class constructor.
+     *
      * @param subdetector the ECAL subdetector object
      */
     EcalConditions(final Subdetector subdetector) {
@@ -54,64 +58,65 @@
     }
 
     /**
+     * Get the channel information for a geometric crystal.
+     *
+     * @param crystal the geometric crystal
+     * @return the channel information or null if does not exist
+     */
+    public EcalChannel getChannel(final EcalCrystal crystal) {
+        return this.crystalMap.getEcalChannel(crystal);
+    }
+
+    /**
+     * Get the map between database IDs and <code>EcalChannel</code> objects.
+     *
+     * @return the channel map
+     */
+    public EcalChannelCollection getChannelCollection() {
+        return this.channelCollection;
+    }
+
+    /**
+     * Get the conditions constants for a specific channel. These will be created if they do not exist for the given
+     * channel, BUT only channels in the channel map are accepted as an argument.
+     *
+     * @param channel the ECAL channel
+     * @return the conditions constants for the channel
+     * @throws IllegalArgumentException if channel does not exist in the channel map
+     */
+    public EcalChannelConstants getChannelConstants(final EcalChannel channel) {
+        // This channel must come from the map.
+        if (!this.channelCollection.contains(channel)) {
+            System.err.println("Channel not found in map: " + channel);
+            throw new IllegalArgumentException("Channel was not found in map.");
+        }
+        // If channel has no data yet, then add it.
+        if (!this.channelConstants.containsKey(channel)) {
+            this.channelConstants.put(channel, new EcalChannelConstants());
+        }
+        return this.channelConstants.get(channel);
+    }
+
+    /**
      * Set the channel map.
+     *
      * @param channelCollection the channel map
      */
     void setChannelCollection(final EcalChannelCollection channelCollection) {
         this.channelCollection = channelCollection;
 
         // Build the map between crystals and channels.
-        crystalMap = new EcalCrystalChannelMap((HPSEcalAPI) subdetector.getDetectorElement(), channelCollection);
+        this.crystalMap = new EcalCrystalChannelMap((HPSEcalAPI) this.subdetector.getDetectorElement(),
+                channelCollection);
     }
 
     /**
-     * Get the map between database IDs and <code>EcalChannel</code> objects.
-     * @return the channel map
-     */
-    public EcalChannelCollection getChannelCollection() {
-        return channelCollection;
-    }
-
-    /**
-     * Get the channel information for a geometric crystal.
-     * @param crystal the geometric crystal
-     * @return the channel information or null if does not exist
-     */
-    public EcalChannel getChannel(final EcalCrystal crystal) {
-        return crystalMap.getEcalChannel(crystal);
-    }
-
-    /**
-     * Get the conditions constants for a specific channel. These will be
-     * created if they do not exist for the given channel, BUT only channels in
-     * the channel map are accepted as an argument.
-     * @param channel the ECAL channel
-     * @return the conditions constants for the channel
-     * @throws IllegalArgumentException if channel does not exist in the channel map
-     */
-    public EcalChannelConstants getChannelConstants(final EcalChannel channel) {
-        // This channel must come from the map.
-        if (!channelCollection.contains(channel)) {
-            System.err.println("Channel not found in map: " + channel);
-            throw new IllegalArgumentException("Channel was not found in map.");
-        }
-        // If channel has no data yet, then add it.
-        if (!channelConstants.containsKey(channel)) {
-            channelConstants.put(channel, new EcalChannelConstants());
-        }
-        return channelConstants.get(channel);
-    }
-
-    /**
-     * This is just used for a divider length in print output.
-     */
-    private static final int DIVIDER_SIZE = 91;
-    
-    /**
      * Convert this object to a string.
+     *
      * @return A string representation of this object.
      */
     // FIXME: The print out from this method looks like a mess.
+    @Override
     public String toString() {
         final StringBuffer sb = new StringBuffer();
 
@@ -149,9 +154,9 @@
         sb.append('\n');
 
         // Loop over all channels.
-        for (EcalChannel channel : channelCollection) {
+        for (final EcalChannel channel : this.channelCollection) {
 
-            final EcalChannelConstants constants = getChannelConstants(channel);
+            final EcalChannelConstants constants = this.getChannelConstants(channel);
 
             final double gain = constants.getGain().getGain();
             final double pedestal = constants.getCalibration().getPedestal();

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalConditionsConverter.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalConditionsConverter.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalConditionsConverter.java	Wed Jul  8 14:47:40 2015
@@ -14,12 +14,11 @@
 import org.lcsim.geometry.Detector;
 
 /**
- * This class loads all ECAL conditions into an {@link EcalConditions} object
- * from the database, based on the current run number known by the conditions
- * manager.
+ * This class loads all ECAL conditions into an {@link EcalConditions} object from the database, based on the current
+ * run number known by the conditions manager.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Jeremy McCormick, SLAC
+ * @author Omar Moreno, UCSC
  * @see EcalConditions
  * @see EcalChannel
  * @see EcalGain
@@ -30,86 +29,44 @@
 public class EcalConditionsConverter implements ConditionsConverter<EcalConditions> {
 
     /**
-     * Get the default {@link EcalChannel} collection.
-     * @param manager the conditions manager
-     * @return the default ECAL channel object collection
-     */
-    protected EcalChannelCollection getEcalChannelCollection(final DatabaseConditionsManager manager) {
-        return manager.getCachedConditions(EcalChannelCollection.class, "ecal_channels").getCachedData();
-    }
-
-    /**
-     * Get the default {@link EcalGain} collection.
-     * @param manager the conditions manager
-     * @return the ECAL channel gain collection
-     */
-    protected EcalGainCollection getEcalGainCollection(final DatabaseConditionsManager manager) {
-        return manager.getCachedConditions(EcalGainCollection.class, "ecal_gains").getCachedData();
-    }
-
-    /**
-     * Get the default collections of {@link EcalBadChannel} objects.
-     * @param manager the conditions manager
-     * @return the collections of ECAL bad channel objects
-     */
-    protected ConditionsSeries<EcalBadChannel, EcalBadChannelCollection> getEcalBadChannelSeries(final DatabaseConditionsManager manager) {
-        return manager.getConditionsSeries(EcalBadChannelCollection.class, "ecal_bad_channels");
-    }
-
-    /**
-     * Get the default {@link EcalCalibration} collection.
-     * @param manager the conditions manager
-     * @return the collection of ECAL channel calibration objects
-     */
-    protected EcalCalibrationCollection getEcalCalibrationCollection(DatabaseConditionsManager manager) {
-        return manager.getCachedConditions(EcalCalibrationCollection.class, "ecal_calibrations").getCachedData();
-    }
-    
-    /**
-     * Get the default {@link EcalTimeShift} collection.
-     * @param manager the conditions manager
-     * @return the collection of ECAL time shift objects
-     */
-    protected EcalTimeShiftCollection getEcalTimeShiftCollection(DatabaseConditionsManager manager) {
-        return manager.getCachedConditions(EcalTimeShiftCollection.class, "ecal_time_shifts").getCachedData();
-    }
-        
-    /**
      * Create combined ECAL conditions object containing all data for the current run.
+     *
      * @param manager the conditions manager
      * @param name the conditions set name (unused but must satisfy conditions API)
      */
-    public final EcalConditions getData(ConditionsManager manager, String name) {
+    @Override
+    public final EcalConditions getData(final ConditionsManager manager, final String name) {
 
         final DatabaseConditionsManager databaseConditionsManager = (DatabaseConditionsManager) manager;
 
         // Get the ECal channel map from the conditions database
-        final EcalChannelCollection channels = getEcalChannelCollection(databaseConditionsManager);
+        final EcalChannelCollection channels = this.getEcalChannelCollection(databaseConditionsManager);
 
         // Create the ECal conditions object that will be used to encapsulate
         // ECal conditions collections
         final Detector detector = databaseConditionsManager.getDetectorObject();
-        final EcalConditions conditions = new EcalConditions(detector.getSubdetector(databaseConditionsManager.getEcalName()));
+        final EcalConditions conditions = new EcalConditions(detector.getSubdetector(databaseConditionsManager
+                .getEcalName()));
 
         // Set the channel map.
         conditions.setChannelCollection(channels);
 
         // Get the ECal gains from the conditions database and add them to the
         // conditions set
-        final EcalGainCollection gains = getEcalGainCollection(databaseConditionsManager);
-        for (EcalGain gain : gains) {
-            final ChannelId channelId = new ChannelId(new int[] { gain.getChannelId() });
+        final EcalGainCollection gains = this.getEcalGainCollection(databaseConditionsManager);
+        for (final EcalGain gain : gains) {
+            final ChannelId channelId = new ChannelId(new int[] {gain.getChannelId()});
             final EcalChannel channel = channels.findChannel(channelId);
             conditions.getChannelConstants(channel).setGain(gain);
         }
 
-        final ConditionsSeries<EcalBadChannel, EcalBadChannelCollection> badChannelSeries = 
-                getEcalBadChannelSeries(databaseConditionsManager);
+        final ConditionsSeries<EcalBadChannel, EcalBadChannelCollection> badChannelSeries = this
+                .getEcalBadChannelSeries(databaseConditionsManager);
         // FIXME: How to get EcalBadChannelCollection here instead for the collection type?
-        //        API of ConditionsSeries and ConditionsSeriesConverter needs to be changed!
-        for (ConditionsObjectCollection<EcalBadChannel> badChannels : badChannelSeries) {
-            for (EcalBadChannel badChannel : badChannels) {
-                final ChannelId channelId = new ChannelId(new int[] { badChannel.getChannelId() });
+        // API of ConditionsSeries and ConditionsSeriesConverter needs to be changed!
+        for (final ConditionsObjectCollection<EcalBadChannel> badChannels : badChannelSeries) {
+            for (final EcalBadChannel badChannel : badChannels) {
+                final ChannelId channelId = new ChannelId(new int[] {badChannel.getChannelId()});
                 final EcalChannel channel = channels.findChannel(channelId);
                 conditions.getChannelConstants(channel).setBadChannel(true);
             }
@@ -117,9 +74,9 @@
 
         // Get the ECal calibrations from the conditions database and add them
         // to the conditions set.
-        final EcalCalibrationCollection calibrations = getEcalCalibrationCollection(databaseConditionsManager);
-        for (EcalCalibration calibration : calibrations) {
-            final ChannelId channelId = new ChannelId(new int[] { calibration.getChannelId() });
+        final EcalCalibrationCollection calibrations = this.getEcalCalibrationCollection(databaseConditionsManager);
+        for (final EcalCalibration calibration : calibrations) {
+            final ChannelId channelId = new ChannelId(new int[] {calibration.getChannelId()});
             final EcalChannel channel = channels.findChannel(channelId);
             conditions.getChannelConstants(channel).setCalibration(calibration);
         }
@@ -127,8 +84,8 @@
         // Get the ECal time shifts from the conditions database and add them to
         // the conditions set.
         if (databaseConditionsManager.hasConditionsRecord("ecal_time_shifts")) {
-            EcalTimeShiftCollection timeShifts = getEcalTimeShiftCollection(databaseConditionsManager);
-            for (EcalTimeShift timeShift : timeShifts) {
+            final EcalTimeShiftCollection timeShifts = this.getEcalTimeShiftCollection(databaseConditionsManager);
+            for (final EcalTimeShift timeShift : timeShifts) {
                 final ChannelId channelId = new ChannelId(new int[] {timeShift.getChannelId()});
                 final EcalChannel channel = channels.findChannel(channelId);
                 conditions.getChannelConstants(channel).setTimeShift(timeShift);
@@ -142,9 +99,62 @@
     }
 
     /**
+     * Get the default collections of {@link EcalBadChannel} objects.
+     *
+     * @param manager the conditions manager
+     * @return the collections of ECAL bad channel objects
+     */
+    protected ConditionsSeries<EcalBadChannel, EcalBadChannelCollection> getEcalBadChannelSeries(
+            final DatabaseConditionsManager manager) {
+        return manager.getConditionsSeries(EcalBadChannelCollection.class, "ecal_bad_channels");
+    }
+
+    /**
+     * Get the default {@link EcalCalibration} collection.
+     *
+     * @param manager the conditions manager
+     * @return the collection of ECAL channel calibration objects
+     */
+    protected EcalCalibrationCollection getEcalCalibrationCollection(final DatabaseConditionsManager manager) {
+        return manager.getCachedConditions(EcalCalibrationCollection.class, "ecal_calibrations").getCachedData();
+    }
+
+    /**
+     * Get the default {@link EcalChannel} collection.
+     *
+     * @param manager the conditions manager
+     * @return the default ECAL channel object collection
+     */
+    protected EcalChannelCollection getEcalChannelCollection(final DatabaseConditionsManager manager) {
+        return manager.getCachedConditions(EcalChannelCollection.class, "ecal_channels").getCachedData();
+    }
+
+    /**
+     * Get the default {@link EcalGain} collection.
+     *
+     * @param manager the conditions manager
+     * @return the ECAL channel gain collection
+     */
+    protected EcalGainCollection getEcalGainCollection(final DatabaseConditionsManager manager) {
+        return manager.getCachedConditions(EcalGainCollection.class, "ecal_gains").getCachedData();
+    }
+
+    /**
+     * Get the default {@link EcalTimeShift} collection.
+     *
+     * @param manager the conditions manager
+     * @return the collection of ECAL time shift objects
+     */
+    protected EcalTimeShiftCollection getEcalTimeShiftCollection(final DatabaseConditionsManager manager) {
+        return manager.getCachedConditions(EcalTimeShiftCollection.class, "ecal_time_shifts").getCachedData();
+    }
+
+    /**
      * Get the type handled by this converter.
+     *
      * @return the type handled by this converter
      */
+    @Override
     public final Class<EcalConditions> getType() {
         return EcalConditions.class;
     }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalConditionsUtil.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalConditionsUtil.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalConditionsUtil.java	Wed Jul  8 14:47:40 2015
@@ -7,20 +7,27 @@
 import org.lcsim.detector.identifier.Identifier;
 
 /**
- * This is a set of utility methods for the ECAL that use the database
- * conditions system.
+ * This is a set of utility methods for the ECAL that use the database conditions system.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public final class EcalConditionsUtil {
 
     /**
      * The combined ECAL conditions object.
      */
-    private EcalConditions conditions;
+    private final EcalConditions conditions;
+
+    /**
+     * Constructor which will find the ECAL conditions from the static conditions manager instance.
+     */
+    public EcalConditionsUtil() {
+        this.conditions = DatabaseConditionsManager.getInstance().getEcalConditions();
+    }
 
     /**
      * Constructor which uses external reference to conditions object.
+     *
      * @param conditions the ECAL conditions object
      */
     public EcalConditionsUtil(final EcalConditions conditions) {
@@ -28,15 +35,8 @@
     }
 
     /**
-     * Constructor which will find the ECAL conditions from the static
-     * conditions manager instance.
-     */
-    public EcalConditionsUtil() {
-        conditions = DatabaseConditionsManager.getInstance().getEcalConditions();
-    }
-
-    /**
      * Find a channel object from a cell ID, e.g. from a <code>CalorimeterHit</code>.
+     *
      * @param helper the identifier helper of the hit
      * @param cellId the cell ID of the hit
      * @return the corresponding ECAL channel found from the physical (geometric) ID information
@@ -52,30 +52,32 @@
         final int y = helper.getValue(id, "iy");
 
         // Create an ID to searching in the channel collection.
-        final GeometryId geometryId = new GeometryId(helper, new int[] { system, x, y });
+        final GeometryId geometryId = new GeometryId(helper, new int[] {system, x, y});
 
         // Find and return the channel object.
-        return conditions.getChannelCollection().findChannel(geometryId);
+        return this.conditions.getChannelCollection().findChannel(geometryId);
     }
 
     /**
      * Get the DAQ crate number from a cell ID.
+     *
      * @param helper the identifier helper of the hit
      * @param cellId the cell ID of the hit
      * @return the crate number of the channel
      */
     public int getCrate(final IIdentifierHelper helper, final long cellId) {
-        return findChannel(helper, cellId).getCrate();
+        return this.findChannel(helper, cellId).getCrate();
     }
 
     /**
      * Get the DAQ slot number from a cell ID.
+     *
      * @param helper the identifier helper of the hit
      * @param cellId the cell ID of the hit
      * @return the slot number of the channel
      */
     public int getSlot(final IIdentifierHelper helper, final long cellId) {
-        return findChannel(helper, cellId).getSlot();
+        return this.findChannel(helper, cellId).getSlot();
     }
 
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalCrystalChannelMap.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalCrystalChannelMap.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalCrystalChannelMap.java	Wed Jul  8 14:47:40 2015
@@ -1,7 +1,6 @@
 package org.hps.conditions.ecal;
 
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
 import org.hps.conditions.ecal.EcalChannel.EcalChannelCollection;
@@ -9,65 +8,68 @@
 import org.lcsim.detector.converter.compact.HPSEcalAPI;
 
 /**
- * This is a convenience utility for associating the geometric crystal
- * objects with the conditions system channel information and vice versa. 
- * 
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * This is a convenience utility for associating the geometric crystal objects with the conditions system channel
+ * information and vice versa.
+ *
+ * @author Jeremy McCormick, SLAC
  */
 final class EcalCrystalChannelMap {
 
     /**
+     * Map of channel to crystal.
+     */
+    private final Map<EcalChannel, EcalCrystal> channelMap = new HashMap<EcalChannel, EcalCrystal>();
+
+    /**
      * Map of crystal to channel.
      */
-    private Map<EcalCrystal, EcalChannel> crystalMap = new HashMap<EcalCrystal, EcalChannel>();
-
-    /**
-     * Map of channel to crystal.
-     */
-    private Map<EcalChannel, EcalCrystal> channelMap = new HashMap<EcalChannel, EcalCrystal>();
+    private final Map<EcalCrystal, EcalChannel> crystalMap = new HashMap<EcalCrystal, EcalChannel>();
 
     /**
      * Creates the map between crystals and channels.
+     *
      * @param api the ECAL geometry API
      * @param channels the list of channels
      */
     EcalCrystalChannelMap(final HPSEcalAPI api, final EcalChannelCollection channels) {
 
         // Map crystals to channels.
-        for (EcalCrystal crystal : api.getCrystals()) {
+        for (final EcalCrystal crystal : api.getCrystals()) {
             final EcalChannel channel = channels.findGeometric(crystal.getIdentifier().getValue());
             if (channel == null) {
                 throw new RuntimeException("ECAL channel was not found for ID: " + crystal.getExpandedIdentifier());
             }
-            crystalMap.put(crystal, channel);
+            this.crystalMap.put(crystal, channel);
         }
 
         // Map channels to crystals.
-        for (EcalChannel channel : channels) {
+        for (final EcalChannel channel : channels) {
             final EcalCrystal crystal = api.getCrystal(channel.getX(), channel.getY());
             if (crystal == null) {
-                throw new RuntimeException("ECAl crystal was not found for channel X Y: "
-                        + channel.getX() + " " + channel.getY());
+                throw new RuntimeException("ECAl crystal was not found for channel X Y: " + channel.getX() + " "
+                        + channel.getY());
             }
-            channelMap.put(channel, crystal);
+            this.channelMap.put(channel, crystal);
         }
     }
 
     /**
      * Get a channel from a crystal.
+     *
      * @param crystal the crystal's geometry object
      * @return the channel information or <code>null</code> if does not exist
      */
     EcalChannel getEcalChannel(final EcalCrystal crystal) {
-        return crystalMap.get(crystal);
+        return this.crystalMap.get(crystal);
     }
 
     /**
      * Get a crystal from a channel.
+     *
      * @param channel the ECAL channel object
      * @return the crystal's geometry object or <code>null</code> if does not exist
      */
     EcalCrystal getEcalCrystal(final EcalChannel channel) {
-        return channelMap.get(channel);
-    } 
+        return this.channelMap.get(channel);
+    }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalGain.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalGain.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalGain.java	Wed Jul  8 14:47:40 2015
@@ -4,18 +4,16 @@
 
 import org.hps.conditions.api.BaseConditionsObject;
 import org.hps.conditions.api.BaseConditionsObjectCollection;
-import org.hps.conditions.database.Converter;
+import org.hps.conditions.api.ConditionsObjectCollection;
 import org.hps.conditions.database.Field;
-import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
 
 /**
  * A per channel ECAL gain value.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
-@Table(names = { "ecal_gains", "test_run_ecal_gains", "ecal_hardware_gains" })
-@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED)
+@Table(names = {"ecal_gains", "test_run_ecal_gains"})
 public final class EcalGain extends BaseConditionsObject {
 
     /**
@@ -25,23 +23,17 @@
     public static final class EcalGainCollection extends BaseConditionsObjectCollection<EcalGain> {
 
         /**
-         * Sort and return a copy of the collection.
-         * @return A sorted copy of the collection.
-         */
-        public BaseConditionsObjectCollection<EcalGain> sorted() {
-            return sorted(new ChannelIdComparator());
-        }
-
-        /**
          * Comparison implementation by channel ID.
          */
         class ChannelIdComparator implements Comparator<EcalGain> {
             /**
              * Compare two objects by their channel ID.
+             *
              * @param o1 The first object.
              * @param o2 The second object.
              * @return -1, 0 or 1 if first channel ID is less than, equal to, or greater than second.
              */
+            @Override
             public int compare(final EcalGain o1, final EcalGain o2) {
                 if (o1.getChannelId() < o2.getChannelId()) {
                     return -1;
@@ -53,6 +45,25 @@
             }
 
         }
+
+        /**
+         * Sort and return a copy of the collection.
+         *
+         * @return A sorted copy of the collection.
+         */
+        public ConditionsObjectCollection<EcalGain> sorted() {
+            return this.sorted(new ChannelIdComparator());
+        }
+    }
+
+    /**
+     * Get the ECal channel ID.
+     *
+     * @return the ECal channel ID
+     */
+    @Field(names = {"ecal_channel_id"})
+    public Integer getChannelId() {
+        return this.getFieldValue("ecal_channel_id");
     }
 
     /**
@@ -60,18 +71,8 @@
      *
      * @return the gain value
      */
-    @Field(names = { "gain" })
-    public double getGain() {
-        return getFieldValue("gain");
-    }
-
-    /**
-     * Get the ECal channel ID.
-     *
-     * @return the ECal channel ID
-     */
-    @Field(names = { "ecal_channel_id" })
-    public int getChannelId() {
-        return getFieldValue("ecal_channel_id");
+    @Field(names = {"gain"})
+    public Double getGain() {
+        return this.getFieldValue("gain");
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalLed.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalLed.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalLed.java	Wed Jul  8 14:47:40 2015
@@ -4,19 +4,16 @@
 
 import org.hps.conditions.api.BaseConditionsObject;
 import org.hps.conditions.api.BaseConditionsObjectCollection;
-import org.hps.conditions.database.Converter;
+import org.hps.conditions.api.ConditionsObjectCollection;
 import org.hps.conditions.database.Field;
-import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
-import org.hps.conditions.ecal.EcalGain.EcalGainCollection.ChannelIdComparator;
 
 /**
  * A conditions class for representing the setup of the LED system in the ECAL for one channel.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 @Table(names = "ecal_leds")
-@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED)
 public final class EcalLed extends BaseConditionsObject {
 
     /**
@@ -26,25 +23,17 @@
     public static class EcalLedCollection extends BaseConditionsObjectCollection<EcalLed> {
 
         /**
-         * Sort and return a copy of this collection.
-         * 
-         * @return the new sorted collection
-         */
-        public BaseConditionsObjectCollection<EcalLed> sorted() {
-            return sorted(new ChannelIdComparator());
-        }
-
-        /**
          * Comparison implementation by channel ID.
          */
         class ChannelIdComparator implements Comparator<EcalLed> {
             /**
              * Compare two objects by channel ID.
-             * 
+             *
              * @param o1 the first object
              * @param o2 the second object
              * @return -1, 0, or 1 if first channel ID is less than, equal to or greater than the first
              */
+            @Override
             public int compare(final EcalLed o1, final EcalLed o2) {
                 if (o1.getEcalChannelId() < o2.getEcalChannelId()) {
                     return -1;
@@ -56,65 +45,74 @@
             }
 
         }
+
+        /**
+         * Sort and return a copy of this collection.
+         *
+         * @return the new sorted collection
+         */
+        public ConditionsObjectCollection<EcalLed> sorted() {
+            return this.sorted(new ChannelIdComparator());
+        }
+    }
+
+    /**
+     * Get the amplitude high setting.
+     *
+     * @return the amplitude high setting
+     */
+    @Field(names = {"amplitude_high"})
+    public Double getAmplitudeHigh() {
+        return this.getFieldValue("amplitude_high");
+    }
+
+    /**
+     * Get the amplitude low setting.
+     *
+     * @return the amplitude low setting
+     */
+    @Field(names = {"amplitude_low"})
+    public Double getAmplitudeLow() {
+        return this.getFieldValue("amplitude_low");
+    }
+
+    /**
+     * Get the crate number assigned to this crystal.
+     *
+     * @return the crate number
+     */
+    @Field(names = {"crate"})
+    public Integer getCrateNumber() {
+        return this.getFieldValue("crate");
     }
 
     /**
      * Get the ECAL channel ID.
-     * 
+     *
      * @return the ECAL channel ID
      */
-    @Field(names = { "ecal_channel_id" })
-    public int getEcalChannelId() {
-        return getFieldValue("ecal_channel_id");
-    }
-
-    /**
-     * Get the crate number assigned to this crystal.
-     * 
-     * @return the crate number
-     */
-    @Field(names = { "crate" })
-    public int getCrateNumber() {
-        return getFieldValue("crate");
+    @Field(names = {"ecal_channel_id"})
+    public Integer getEcalChannelId() {
+        return this.getFieldValue("ecal_channel_id");
     }
 
     /**
      * Get the LED number assigned to this crystal.
-     * 
+     *
      * @return the LED number
      */
-    @Field(names = { "number" })
-    public int getLedNumber() {
-        return getFieldValue("number");
+    @Field(names = {"number"})
+    public Integer getLedNumber() {
+        return this.getFieldValue("number");
     }
 
     /**
      * Get the time delay of this channel.
-     * 
+     *
      * @return the time delay
      */
-    @Field(names = { "time_delay" })
-    public double getTimeDelay() {
-        return getFieldValue("time_delay");
-    }
-
-    /**
-     * Get the amplitude high setting.
-     * 
-     * @return the amplitude high setting
-     */
-    @Field(names = { "amplitude_high" })
-    public double getAmplitudeHigh() {
-        return getFieldValue("amplitude_high");
-    }
-
-    /**
-     * Get the amplitude low setting.
-     * 
-     * @return the amplitude low setting
-     */
-    @Field(names = { "amplitude_low" })
-    public double getAmplitudeLow() {
-        return getFieldValue("amplitude_low");
+    @Field(names = {"time_delay"})
+    public Double getTimeDelay() {
+        return this.getFieldValue("time_delay");
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalLedCalibration.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalLedCalibration.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalLedCalibration.java	Wed Jul  8 14:47:40 2015
@@ -2,24 +2,20 @@
 
 import org.hps.conditions.api.BaseConditionsObject;
 import org.hps.conditions.api.BaseConditionsObjectCollection;
-import org.hps.conditions.database.Converter;
 import org.hps.conditions.database.Field;
-import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
 
 /**
  * ECAL LED calibration information per channel.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 @Table(names = "ecal_led_calibrations")
-@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED)
 public final class EcalLedCalibration extends BaseConditionsObject {
 
     /**
      * Generic collection class for these objects.
      */
-    @SuppressWarnings("serial")
     public static class EcalLedCalibrationCollection extends BaseConditionsObjectCollection<EcalLedCalibration> {
     }
 
@@ -31,7 +27,7 @@
 
     /**
      * Fully qualified constructor.
-     * 
+     *
      * @param channelId the ECAL channel ID (not the LED channel ID)
      * @param ledResponse the mean of the LED response
      * @param rms the RMS of the LED response
@@ -44,31 +40,31 @@
 
     /**
      * Get the ECAL channel ID.
-     * 
+     *
      * @return The ECAL channel ID.
      */
-    @Field(names = { "ecal_channel_id" })
-    public int getEcalChannelId() {
-        return getFieldValue("ecal_channel_id");
+    @Field(names = {"ecal_channel_id"})
+    public Integer getEcalChannelId() {
+        return this.getFieldValue("ecal_channel_id");
     }
 
     /**
      * Get the average LED response.
-     * 
+     *
      * @return the average LED response
      */
-    @Field(names = { "led_response" })
-    public double getLedResponse() {
-        return getFieldValue("led_response");
+    @Field(names = {"led_response"})
+    public Double getLedResponse() {
+        return this.getFieldValue("led_response");
     }
 
     /**
      * Get the RMS of the LED response.
-     * 
+     *
      * @return the RMS of the LED response
      */
-    @Field(names = { "rms" })
-    public int getRms() {
-        return getFieldValue("rms");
+    @Field(names = {"rms"})
+    public Integer getRms() {
+        return this.getFieldValue("rms");
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalTimeShift.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalTimeShift.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalTimeShift.java	Wed Jul  8 14:47:40 2015
@@ -4,33 +4,22 @@
 
 import org.hps.conditions.api.BaseConditionsObject;
 import org.hps.conditions.api.BaseConditionsObjectCollection;
-import org.hps.conditions.database.Converter;
+import org.hps.conditions.api.ConditionsObjectCollection;
 import org.hps.conditions.database.Field;
-import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
 
 /**
  * This class represents a time shift calibration value for an ECAL channel.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 @Table(names = {"ecal_time_shifts", "test_run_ecal_time_shifts"})
-@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED)
 public final class EcalTimeShift extends BaseConditionsObject {
 
     /**
      * A collection of {@link EcalTimeShift} objects.
      */
-    @SuppressWarnings("serial")
     public static final class EcalTimeShiftCollection extends BaseConditionsObjectCollection<EcalTimeShift> {
-
-        /**
-         * Sort and return a copy of the collection.
-         * @return The sorted copy of the collection.
-         */
-        public BaseConditionsObjectCollection<EcalTimeShift> sorted() {
-            return sorted(new ChannelIdComparator());
-        }
 
         /**
          * Compare two objects by their channel ID.
@@ -38,11 +27,13 @@
         class ChannelIdComparator implements Comparator<EcalTimeShift> {
             /**
              * Compare two objects by channel ID.
+             *
              * @param o1 the first object
              * @param o2 the second object
              * @return -1, 0 or 1 if first channel ID is less than, equal to, or greater than second
              */
-            public int compare(EcalTimeShift o1, EcalTimeShift o2) {
+            @Override
+            public int compare(final EcalTimeShift o1, final EcalTimeShift o2) {
                 if (o1.getChannelId() < o2.getChannelId()) {
                     return -1;
                 } else if (o1.getChannelId() > o2.getChannelId()) {
@@ -52,23 +43,34 @@
                 }
             }
         }
+
+        /**
+         * Sort and return a copy of the collection.
+         *
+         * @return The sorted copy of the collection.
+         */
+        public ConditionsObjectCollection<EcalTimeShift> sorted() {
+            return this.sorted(new ChannelIdComparator());
+        }
     }
 
     /**
      * Get the channel ID.
+     *
      * @return the ECAL channel ID
      */
     @Field(names = {"ecal_channel_id"})
-    public int getChannelId() {
-        return getFieldValue("ecal_channel_id");
+    public Integer getChannelId() {
+        return this.getFieldValue("ecal_channel_id");
     }
 
     /**
      * Get the time shift in nanoseconds
+     *
      * @return the time shift in nanoseconds
      */
     @Field(names = {"time_shift"})
-    public double getTimeShift() {
-        return getFieldValue("time_shift");
+    public Double getTimeShift() {
+        return this.getFieldValue("time_shift");
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/ecal/TestRunEcalConditionsConverter.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/TestRunEcalConditionsConverter.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/TestRunEcalConditionsConverter.java	Wed Jul  8 14:47:40 2015
@@ -9,57 +9,69 @@
 import org.hps.conditions.ecal.EcalTimeShift.EcalTimeShiftCollection;
 
 /**
- * This class loads all Test Run ECAL conditions into an {@link EcalConditions} object
- * from the database.
+ * This class loads all Test Run ECAL conditions into an {@link EcalConditions} object from the database.
  * <p>
  * The default names are overridden to use tables that contain only Test Run data.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Jeremy McCormick, SLAC
+ * @author Omar Moreno, UCSC
  */
 public final class TestRunEcalConditionsConverter extends EcalConditionsConverter {
 
     /**
-     * Get the {@link EcalChannel} collection for Test Run.
-     * @param manager the conditions manager
-     * @return the Test Run ECAL channel collection
-     */
-    protected EcalChannelCollection getEcalChannelCollection(DatabaseConditionsManager manager) {
-        return manager.getCachedConditions(EcalChannelCollection.class, "test_run_ecal_channels").getCachedData();
-    }
-    /**
-     * Get the {@link EcalGain} collection for Test Run.
-     * @param manager the conditions manager
-     * @return the Test Run ECAL gain collection
-     */     
-    protected EcalGainCollection getEcalGainCollection(DatabaseConditionsManager manager) {
-        return manager.getCachedConditions(EcalGainCollection.class, "test_run_ecal_gains").getCachedData();
-    }
-    
-    /**
      * Get the collections of {@link EcalBadChannel} objects for Test Run.
+     *
      * @param manager the conditions manager
      * @return the Test Run bad channel collections
      */
-    protected ConditionsSeries<EcalBadChannel, EcalBadChannelCollection> getEcalBadChannelSeries(DatabaseConditionsManager manager) {
+    @Override
+    protected ConditionsSeries<EcalBadChannel, EcalBadChannelCollection> getEcalBadChannelSeries(
+            final DatabaseConditionsManager manager) {
         return manager.getConditionsSeries(EcalBadChannelCollection.class, "test_run_ecal_bad_channels");
     }
 
     /**
      * Get the {@link EcalCalibration} collection for Test Run.
+     *
      * @param manager the conditions manager
-     * @return the Test Run ECAL calibration collection 
+     * @return the Test Run ECAL calibration collection
      */
-    protected EcalCalibrationCollection getEcalCalibrationCollection(DatabaseConditionsManager manager) {
-        return manager.getCachedConditions(EcalCalibrationCollection.class, "test_run_ecal_calibrations").getCachedData();
+    @Override
+    protected EcalCalibrationCollection getEcalCalibrationCollection(final DatabaseConditionsManager manager) {
+        return manager.getCachedConditions(EcalCalibrationCollection.class, "test_run_ecal_calibrations")
+                .getCachedData();
+    }
+
+    /**
+     * Get the {@link EcalChannel} collection for Test Run.
+     *
+     * @param manager the conditions manager
+     * @return the Test Run ECAL channel collection
+     */
+    @Override
+    protected EcalChannelCollection getEcalChannelCollection(final DatabaseConditionsManager manager) {
+        return manager.getCachedConditions(EcalChannelCollection.class, "test_run_ecal_channels").getCachedData();
+    }
+
+    /**
+     * Get the {@link EcalGain} collection for Test Run.
+     *
+     * @param manager the conditions manager
+     * @return the Test Run ECAL gain collection
+     */
+    @Override
+    protected EcalGainCollection getEcalGainCollection(final DatabaseConditionsManager manager) {
+        return manager.getCachedConditions(EcalGainCollection.class, "test_run_ecal_gains").getCachedData();
     }
 
     /**
      * Get the {@link EcalTimeShift} collection for Test Run.
+     *
      * @param manager the conditions manager
      * @return the Test Run ECAL time shift collection
      */
-    protected EcalTimeShiftCollection getEcalTimeShiftCollection(DatabaseConditionsManager manager) {
+    @Override
+    protected EcalTimeShiftCollection getEcalTimeShiftCollection(final DatabaseConditionsManager manager) {
         return manager.getCachedConditions(EcalTimeShiftCollection.class, "test_run_ecal_time_shifts").getCachedData();
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/ecal/package-info.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/package-info.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/package-info.java	Wed Jul  8 14:47:40 2015
@@ -4,23 +4,22 @@
  * <p>
  * Each {@link EcalChannel} represents one physical crystal in the detector.
  * <p>
- * The {@link EcalBadChannel} is a channel that is malfunctioning or dead and should not 
- * be used for reconstruction.  It is up to the reconstruction Drivers to filter out 
- * these channels.
+ * The {@link EcalBadChannel} is a channel that is malfunctioning or dead and should not be used for reconstruction. It
+ * is up to the reconstruction Drivers to filter out these channels.
  * <p>
- * The {@link EcalCalibration} contains the pedestal and noise values for a channel, 
- * which are the mean and the standard deviation of the digitized preamplifier output.
+ * The {@link EcalCalibration} contains the pedestal and noise values for a channel, which are the mean and the standard
+ * deviation of the digitized preamplifier output.
  * <p>
  * The {@link EcalGain} is the channel gain in units of MeV/ADC counts.
  * <p>
  * The {@link EcalTimeShift} is a time shift in the electronics response.
  * <p>
- * The {@link EcalLedCalibration} is calibration information for the LED attached to
- * an ECAL channel.
+ * The {@link EcalLedCalibration} is calibration information for the LED attached to an ECAL channel.
  * <p>
- * The energy of a hit is reconstructed by multiplying the gain by the pedestal-subtracted
- * ADC integral (e.g. in Test Run 2012 data).
- * 
- * @author Jeremy McCormick <[log in to unmask]>
+ * The energy of a hit is reconstructed by multiplying the gain by the pedestal-subtracted ADC integral (e.g. in Test
+ * Run 2012 data).
+ *
+ * @author Jeremy McCormick, SLAC
  */
 package org.hps.conditions.ecal;
+

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/package-info.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/package-info.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/package-info.java	Wed Jul  8 14:47:40 2015
@@ -1,10 +1,11 @@
 /**
- * The HPS conditions module provides facilities for accessing time dependent conditions for a detector at runtime
- * using a framework built on the LCSim conditions system.  The {@link DatabaseConditionsReader} has a set of
- * converters for reading data from tables using SQL queries and creating appropriate, typed objects for them.
+ * The HPS conditions module provides facilities for accessing time dependent conditions for a detector at runtime using
+ * a framework built on the LCSim conditions system. The {@link DatabaseConditionsReader} has a set of converters for
+ * reading data from tables using SQL queries and creating appropriate, typed objects for them.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  * @see org.hps.conditions.api
  * @see org.hps.conditions.database
  */
 package org.hps.conditions;
+

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtChannel.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtChannel.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtChannel.java	Wed Jul  8 14:47:40 2015
@@ -6,15 +6,84 @@
 
 import org.hps.conditions.api.BaseConditionsObject;
 import org.hps.conditions.api.BaseConditionsObjectCollection;
+import org.hps.conditions.api.ConditionsObjectException;
 import org.hps.conditions.database.Field;
 import org.hps.util.Pair;
 
 /**
  * This abstract class provides basic setup information for an SVT sensor channel.
  *
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Jeremy McCormick, SLAC
+ * @author Omar Moreno, UCSC
  */
 public abstract class AbstractSvtChannel extends BaseConditionsObject {
+
+    /**
+     * Collection implementation for {@link AbstractSvtChannel}.
+     *
+     * @param <T> A type extending AbstractSvtChannel
+     */
+    @SuppressWarnings("serial")
+    public abstract static class AbstractSvtChannelCollection<T extends AbstractSvtChannel> extends
+            BaseConditionsObjectCollection<T> {
+
+        /**
+         * Map of channel number to object.
+         */
+        private final Map<Integer, T> channelMap = new HashMap<Integer, T>();
+
+        /**
+         * Add a channel of type extending {@link AbstractSvtChannel} to the channel map.
+         *
+         * @param channel channel of a type extending {@link AbstractSvtChannel}
+         */
+        @Override
+        public final boolean add(final T channel) throws ConditionsObjectException {
+
+            // If it doesn't exist, add the channel to the channel map
+            if (this.channelMap.containsKey(channel.getChannelID())) {
+                throw new IllegalArgumentException("[ " + this.getClass().getSimpleName()
+                        + " ]: Channel ID already exists: " + channel.getChannelID());
+            }
+            this.channelMap.put(channel.getChannelID(), channel);
+
+            // Add to the collection
+            return super.add(channel);
+        }
+
+        /**
+         * Find the collection of channels of type extending {@link AbstractSvtChannel} that match a DAQ pair (FEB ID
+         * and FEB Hybrid ID).
+         *
+         * @param pair the DAQ pair
+         * @return the channels matching the DAQ pair or null if not found
+         */
+        public abstract Collection<T> find(final Pair<Integer, Integer> pair);
+
+        /**
+         * Find a channel of type extending {@link AbstractSvtChannel} using the channel ID.
+         *
+         * @param channelID the channel ID
+         * @return an SVT channel of type extending {@link AbstractSvtChannel}
+         */
+        public final T findChannel(final int channelID) {
+            return this.channelMap.get(channelID);
+        }
+
+        /**
+         * Convert this object to a human readable string.
+         *
+         * @return This object converted to a string.
+         */
+        @Override
+        public final String toString() {
+            final StringBuffer buff = new StringBuffer();
+            for (final T channel : this) {
+                buff.append(channel.toString() + '\n');
+            }
+            return buff.toString();
+        }
+    }
 
     /**
      * Default number of samples to read out.
@@ -23,107 +92,40 @@
     public static final int MAX_NUMBER_OF_SAMPLES = 6;
 
     /**
-     * Collection implementation for {@link AbstractSvtChannel}.
+     * Get the channel number (0-639). This is different from the ID.
      *
-     * @param <T> A type extending AbstractSvtChannel
+     * @return the channel number
      */
-    @SuppressWarnings("serial")
-    public abstract static class AbstractSvtChannelCollection<T extends AbstractSvtChannel>
-        extends BaseConditionsObjectCollection<T> {
-
-        /**
-         * Map of channel number to object.
-         */
-        private Map<Integer, T> channelMap = new HashMap<Integer, T>();
-
-        /**
-         * Add a channel of type extending {@link AbstractSvtChannel} to the channel map.
-         *
-         * @param channel channel of a type extending {@link AbstractSvtChannel}
-         */
-        @Override
-        public final boolean add(final T channel) {
-
-            // If it doesn't exist, add the channel to the channel map
-            if (channelMap.containsKey(channel.getChannelID())) {
-                throw new IllegalArgumentException("[ " + this.getClass().getSimpleName()
-                        + " ]: Channel ID already exists: " + channel.getChannelID());
-            }
-            channelMap.put(channel.getChannelID(), channel);
-
-            // Add to the collection
-            return super.add(channel);
-        }
-
-        /**
-         *  Find a channel of type extending {@link AbstractSvtChannel} using the channel ID.
-         *
-         *  @param channelID the channel ID
-         *  @return an SVT channel of type extending {@link AbstractSvtChannel}
-         */
-        public final T findChannel(final int channelID) {
-            return channelMap.get(channelID);
-        }
-
-        /**
-         *  Find the collection of channels of type extending {@link AbstractSvtChannel} that match a DAQ pair
-         *  (FEB ID and FEB Hybrid ID).
-         *
-         *  @param pair the DAQ pair
-         *  @return the channels matching the DAQ pair or null if not found
-         */
-        public abstract Collection<T> find(final Pair<Integer, Integer> pair);
-
-        /**
-         *  Convert this object to a human readable string.
-         *
-         *  @return This object converted to a string.
-         */
-        @Override
-        public final String toString() {
-            final StringBuffer buff = new StringBuffer();
-            for (T channel : this) {
-                buff.append(channel.toString() + '\n');
-            }
-            return buff.toString();
-        }
+    @Field(names = {"channel"})
+    public final Integer getChannel() {
+        return this.getFieldValue("channel");
     }
 
     /**
-     *  Get the channel ID.
+     * Get the channel ID.
      *
-     *  @return the SVT channel ID
+     * @return the SVT channel ID
      */
     @Field(names = {"channel_id"})
-    public final int getChannelID() {
-        return getFieldValue("channel_id");
+    public final Integer getChannelID() {
+        return this.getFieldValue("channel_id");
     }
 
     /**
-     *  Get the channel number (0-639). This is different from the ID.
+     * Set the channel number (0-639). This is different from the ID.
      *
-     *  @return the channel number
+     * @param channel the channel number
      */
-    @Field(names = {"channel"})
-    public final int getChannel() {
-        return getFieldValue("channel");
+    public final void setChannel(final int channel) {
+        this.setFieldValue("channel", channel);
     }
 
     /**
-     *  Set the channel ID.
+     * Set the channel ID.
      *
-     *  @param channelID the SVT channel ID
+     * @param channelID the SVT channel ID
      */
     public final void setChannelID(final int channelID) {
         this.setFieldValue("channel_id", channelID);
     }
-
-    /**
-     *  Set the channel number (0-639). This is different from the ID.
-     *
-     *  @param channel the channel number
-     */
-    public final void setChannel(final int channel) {
-        this.setFieldValue("channel", channel);
-    }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtConditions.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtConditions.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtConditions.java	Wed Jul  8 14:47:40 2015
@@ -10,21 +10,14 @@
 /**
  * Abstract class providing some of the common functionality used to define an SVT conditions object.
  *
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Omar Moreno, UCSC
  */
 public abstract class AbstractSvtConditions {
 
     /**
      * A map between the channel object and its conditions constants.
      */
-    private Map<AbstractSvtChannel, ChannelConstants> channelData =
-            new HashMap<AbstractSvtChannel, ChannelConstants>();
-
-    /**
-     * The time shift collection.
-     */
-    // FIXME: Should be private with accessor methods.
-    protected AbstractSvtT0Shift.AbstractSvtT0ShiftCollection<? extends AbstractSvtT0Shift> t0Shifts = null;
+    private final Map<AbstractSvtChannel, ChannelConstants> channelData = new HashMap<AbstractSvtChannel, ChannelConstants>();
 
     /**
      * The channel map.
@@ -39,16 +32,14 @@
     protected AbstractSvtDaqMapping.AbstractSvtDaqMappingCollection<? extends AbstractSvtDaqMapping> daqMap = null;
 
     /**
-     * Get the DAQ map associated with these conditions.
-     *
-     * @return The SVT DAQ map.
+     * The time shift collection.
      */
-    public abstract AbstractSvtDaqMappingCollection<? extends AbstractSvtDaqMapping> getDaqMap();
+    // FIXME: Should be private with accessor methods.
+    protected AbstractSvtT0Shift.AbstractSvtT0ShiftCollection<? extends AbstractSvtT0Shift> t0Shifts = null;
 
     /**
-     * Get the conditions constants for a specific channel. These will be
-     * created if they do not exist for the given channel, BUT only channels in
-     * the current channel map are allowed as an argument.
+     * Get the conditions constants for a specific channel. These will be created if they do not exist for the given
+     * channel, BUT only channels in the current channel map are allowed as an argument.
      *
      * @param channel the SVT channel of interest
      * @return the conditions constants for the given channel
@@ -56,15 +47,15 @@
      */
     public final ChannelConstants getChannelConstants(final AbstractSvtChannel channel) {
         // This channel must come from the map.
-        if (!channelMap.contains(channel)) {
+        if (!this.channelMap.contains(channel)) {
             System.err.println("[ " + this.getClass().getSimpleName() + " ]: Channel not found in map => " + channel);
             throw new IllegalArgumentException("Channel was not found in map.");
         }
         // If channel has no data yet, then add it.
-        if (!channelData.containsKey(channel)) {
-            channelData.put(channel, new ChannelConstants());
+        if (!this.channelData.containsKey(channel)) {
+            this.channelData.put(channel, new ChannelConstants());
         }
-        return channelData.get(channel);
+        return this.channelData.get(channel);
     }
 
     /**
@@ -75,11 +66,27 @@
     public abstract AbstractSvtChannelCollection<? extends AbstractSvtChannel> getChannelMap();
 
     /**
+     * Get the DAQ map associated with these conditions.
+     *
+     * @return The SVT DAQ map.
+     */
+    public abstract AbstractSvtDaqMappingCollection<? extends AbstractSvtDaqMapping> getDaqMap();
+
+    /**
      * Get the t0 shifts for this conditions set.
      *
      * @return the t0 shifts by sensor
      */
     public abstract AbstractSvtT0ShiftCollection<? extends AbstractSvtT0Shift> getT0Shifts();
+
+    /**
+     * Set the SVT channel map for this conditions set.
+     *
+     * @param channelMap the SVT channel map for this conditions set
+     */
+    public final void setChannelMap(final AbstractSvtChannelCollection<? extends AbstractSvtChannel> channelMap) {
+        this.channelMap = channelMap;
+    }
 
     /**
      * Set the DAQ map for this conditions set.
@@ -91,15 +98,6 @@
     }
 
     /**
-     * Set the SVT channel map for this conditions set.
-     *
-     * @param channelMap the SVT channel map for this conditions set
-     */
-    public final void setChannelMap(final AbstractSvtChannelCollection<? extends AbstractSvtChannel> channelMap) {
-        this.channelMap = channelMap;
-    }
-
-    /**
      * Set the sensor t0 shifts for this conditions set.
      *
      * @param t0Shifts for this conditions set

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtConditionsConverter.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtConditionsConverter.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtConditionsConverter.java	Wed Jul  8 14:47:40 2015
@@ -14,19 +14,12 @@
 import org.lcsim.util.log.LogUtil;
 
 /**
- * Abstract class providing some of the common methods used in creating SVT
- * conditions objects from the database.
+ * Abstract class providing some of the common methods used in creating SVT conditions objects from the database.
  *
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Omar Moreno, UCSC
  * @param <T> SVT conditions object type
  */
 public abstract class AbstractSvtConditionsConverter<T extends AbstractSvtConditions> implements ConditionsConverter<T> {
-
-    /**
-     * The combined detector conditions object.
-     */
-    // FIXME: Should be private with accessor methods.
-    protected T conditions;
 
     /**
      * Initialize logging.
@@ -34,49 +27,10 @@
     static Logger logger = LogUtil.create(AbstractSvtConditionsConverter.class);
 
     /**
-     * Get the default {@link SvtShapeFitParametersCollection} collection from the manager.
-     * @param manager the current conditions manager
-     * @return the default {@link SvtShapeFitParametersCollection}
+     * The combined detector conditions object.
      */
-    protected SvtShapeFitParametersCollection getSvtShapeFitParametersCollection(final DatabaseConditionsManager manager) {
-        return manager.getCachedConditions(SvtShapeFitParametersCollection.class, "svt_shape_fit_parameters").getCachedData();
-    }
-
-    /**
-     * Get the default {@link SvtBadChannelCollection} collection from the manager.
-     * @param manager the current conditions manager
-     * @return the default {@link SvtBadChannelCollection}
-     */
-    protected SvtBadChannelCollection getSvtBadChannelCollection(final DatabaseConditionsManager manager) {
-        return manager.getCachedConditions(SvtBadChannelCollection.class, "svt_bad_channels").getCachedData();
-    }
-
-    /**
-     * Get the default series of {@link SvtBadChannelCollection} collections from the manager.
-     * @param manager the current conditions manager
-     * @return the default series of {@link SvtBadChannelCollection}
-     */
-    protected ConditionsSeries<SvtBadChannel, SvtBadChannelCollection> getSvtBadChannelSeries(final DatabaseConditionsManager manager) {
-        return manager.getConditionsSeries(SvtBadChannelCollection.class, "svt_bad_channels");
-    }
-
-    /**
-     * Get the default {@link SvtCalibrationCollection} collection from the manager.
-     * @param manager the current conditions manager
-     * @return the default {@link SvtCalibrationCollection}
-     */
-    protected SvtCalibrationCollection getSvtCalibrationCollection(final DatabaseConditionsManager manager) {
-        return manager.getCachedConditions(SvtCalibrationCollection.class, "svt_calibrations").getCachedData();
-    }
-
-    /**
-     * Get the default {@link SvtGainCollection} collection from the manager.
-     * @param manager the current conditions manager
-     * @return the default {@link SvtGainCollection}
-     */
-    protected SvtGainCollection getSvtGainCollection(final DatabaseConditionsManager manager) {
-        return manager.getCachedConditions(SvtGainCollection.class, "svt_gains").getCachedData();
-    }
+    // FIXME: Should be private with accessor methods.
+    protected T conditions;
 
     /**
      * Create and return the SVT conditions object.
@@ -91,45 +45,97 @@
         final DatabaseConditionsManager dbConditionsManager = (DatabaseConditionsManager) manager;
 
         // Get the SVT calibrations (baseline, noise) from the conditions database
-        final SvtCalibrationCollection calibrations = getSvtCalibrationCollection(dbConditionsManager);
-        for (SvtCalibration calibration : calibrations) {
-            final AbstractSvtChannel channel = conditions.getChannelMap().findChannel(calibration.getChannelID());
-            conditions.getChannelConstants(channel).setCalibration(calibration);
+        final SvtCalibrationCollection calibrations = this.getSvtCalibrationCollection(dbConditionsManager);
+        for (final SvtCalibration calibration : calibrations) {
+            final AbstractSvtChannel channel = this.conditions.getChannelMap().findChannel(calibration.getChannelID());
+            this.conditions.getChannelConstants(channel).setCalibration(calibration);
         }
 
         // Get the Channel pulse fit parameters from the conditions database
-        final SvtShapeFitParametersCollection shapeFitParametersCollection =
-                getSvtShapeFitParametersCollection(dbConditionsManager);
-        for (SvtShapeFitParameters shapeFitParameters : shapeFitParametersCollection) {
-            final AbstractSvtChannel channel = conditions.getChannelMap().findChannel(
+        final SvtShapeFitParametersCollection shapeFitParametersCollection = this
+                .getSvtShapeFitParametersCollection(dbConditionsManager);
+        for (final SvtShapeFitParameters shapeFitParameters : shapeFitParametersCollection) {
+            final AbstractSvtChannel channel = this.conditions.getChannelMap().findChannel(
                     shapeFitParameters.getChannelID());
-            conditions.getChannelConstants(channel).setShapeFitParameters(shapeFitParameters);
+            this.conditions.getChannelConstants(channel).setShapeFitParameters(shapeFitParameters);
         }
 
         // Get the bad channels from the conditions database.
         // If there aren't any bad channels, notify the user and move on.
         try {
-            final ConditionsSeries<SvtBadChannel, SvtBadChannelCollection> badChannelSeries =
-                    getSvtBadChannelSeries(dbConditionsManager);
-            for (ConditionsObjectCollection<SvtBadChannel> badChannelCollection : badChannelSeries) {
-                for (SvtBadChannel badChannel : badChannelCollection) {
-                    final AbstractSvtChannel channel = conditions.getChannelMap().findChannel(
+            final ConditionsSeries<SvtBadChannel, SvtBadChannelCollection> badChannelSeries = this
+                    .getSvtBadChannelSeries(dbConditionsManager);
+            for (final ConditionsObjectCollection<SvtBadChannel> badChannelCollection : badChannelSeries) {
+                for (final SvtBadChannel badChannel : badChannelCollection) {
+                    final AbstractSvtChannel channel = this.conditions.getChannelMap().findChannel(
                             badChannel.getChannelId());
-                    conditions.getChannelConstants(channel).setBadChannel(true);
+                    this.conditions.getChannelConstants(channel).setBadChannel(true);
                 }
             }
-        } catch (RuntimeException e) {
+        } catch (final RuntimeException e) {
             logger.warning("A set of SVT bad channels was not found.");
         }
 
         // Get the gains and offsets from the conditions database
-        final SvtGainCollection channelGains = getSvtGainCollection(dbConditionsManager);
-        for (SvtGain channelGain : channelGains) {
+        final SvtGainCollection channelGains = this.getSvtGainCollection(dbConditionsManager);
+        for (final SvtGain channelGain : channelGains) {
             final int channelId = channelGain.getChannelID();
-            final AbstractSvtChannel channel = conditions.getChannelMap().findChannel(channelId);
-            conditions.getChannelConstants(channel).setGain(channelGain);
+            final AbstractSvtChannel channel = this.conditions.getChannelMap().findChannel(channelId);
+            this.conditions.getChannelConstants(channel).setGain(channelGain);
         }
 
-        return conditions;
+        return this.conditions;
+    }
+
+    /**
+     * Get the default {@link SvtBadChannelCollection} collection from the manager.
+     *
+     * @param manager the current conditions manager
+     * @return the default {@link SvtBadChannelCollection}
+     */
+    protected SvtBadChannelCollection getSvtBadChannelCollection(final DatabaseConditionsManager manager) {
+        return manager.getCachedConditions(SvtBadChannelCollection.class, "svt_bad_channels").getCachedData();
+    }
+
+    /**
+     * Get the default series of {@link SvtBadChannelCollection} collections from the manager.
+     *
+     * @param manager the current conditions manager
+     * @return the default series of {@link SvtBadChannelCollection}
+     */
+    protected ConditionsSeries<SvtBadChannel, SvtBadChannelCollection> getSvtBadChannelSeries(
+            final DatabaseConditionsManager manager) {
+        return manager.getConditionsSeries(SvtBadChannelCollection.class, "svt_bad_channels");
+    }
+
+    /**
+     * Get the default {@link SvtCalibrationCollection} collection from the manager.
+     *
+     * @param manager the current conditions manager
+     * @return the default {@link SvtCalibrationCollection}
+     */
+    protected SvtCalibrationCollection getSvtCalibrationCollection(final DatabaseConditionsManager manager) {
+        return manager.getCachedConditions(SvtCalibrationCollection.class, "svt_calibrations").getCachedData();
+    }
+
+    /**
+     * Get the default {@link SvtGainCollection} collection from the manager.
+     *
+     * @param manager the current conditions manager
+     * @return the default {@link SvtGainCollection}
+     */
+    protected SvtGainCollection getSvtGainCollection(final DatabaseConditionsManager manager) {
+        return manager.getCachedConditions(SvtGainCollection.class, "svt_gains").getCachedData();
+    }
+
+    /**
+     * Get the default {@link SvtShapeFitParametersCollection} collection from the manager.
+     *
+     * @param manager the current conditions manager
+     * @return the default {@link SvtShapeFitParametersCollection}
+     */
+    protected SvtShapeFitParametersCollection getSvtShapeFitParametersCollection(final DatabaseConditionsManager manager) {
+        return manager.getCachedConditions(SvtShapeFitParametersCollection.class, "svt_shape_fit_parameters")
+                .getCachedData();
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtDaqMapping.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtDaqMapping.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtDaqMapping.java	Wed Jul  8 14:47:40 2015
@@ -9,7 +9,7 @@
 /**
  * This abstract class provides some of the basic functionality used to access SVT DAQ map variables.
  *
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Omar Moreno, UCSC
  */
 public abstract class AbstractSvtDaqMapping extends BaseConditionsObject {
 
@@ -20,7 +20,7 @@
      */
     @SuppressWarnings("serial")
     public static abstract class AbstractSvtDaqMappingCollection<T extends AbstractSvtDaqMapping> extends
-    BaseConditionsObjectCollection<T> {
+            BaseConditionsObjectCollection<T> {
 
         /**
          * Get a DAQ pair for the given {@link HpsSiSensor}.
@@ -66,9 +66,9 @@
      *
      * @return SVT sensor layer number
      */
-    @Field(names = { "layer" })
+    @Field(names = {"layer"})
     public final int getLayerNumber() {
-        return getFieldValue("layer");
+        return this.getFieldValue("layer");
     }
 
     /**
@@ -78,9 +78,9 @@
      * @see STEREO
      * @return the orientation of the SVT sensor
      */
-    @Field(names = { "orientation" })
+    @Field(names = {"orientation"})
     public final String getOrientation() {
-        return getFieldValue("orientation");
+        return this.getFieldValue("orientation");
     }
 
     /**
@@ -88,9 +88,9 @@
      *
      * @return SVT half (TOP or BOTTOM)
      */
-    @Field(names = { "svt_half" })
+    @Field(names = {"svt_half"})
     public final String getSvtHalf() {
-        return getFieldValue("svt_half");
+        return this.getFieldValue("svt_half");
     }
 
     /**

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtT0Shift.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtT0Shift.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtT0Shift.java	Wed Jul  8 14:47:40 2015
@@ -6,21 +6,21 @@
 import org.hps.util.Pair;
 
 /**
- * Abstract class providing some of the basic functionality used to relate a t0
- * shift value with either a FEB ID/FEB hybrid ID or an FPGA ID/hybrid ID.
- * 
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * Abstract class providing some of the basic functionality used to relate a t0 shift value with either a FEB ID/FEB
+ * hybrid ID or an FPGA ID/hybrid ID.
+ *
+ * @author Omar Moreno, UCSC
  */
 public abstract class AbstractSvtT0Shift extends BaseConditionsObject {
 
     /**
      * The collection implementation for this class.
-     * 
+     *
      * @param <T> the type of the object in this collection which extends {@link AbstractSvtT0Shift}
      */
     @SuppressWarnings("serial")
-    public static abstract class AbstractSvtT0ShiftCollection<T extends AbstractSvtT0Shift> 
-        extends BaseConditionsObjectCollection<T> {
+    public static abstract class AbstractSvtT0ShiftCollection<T extends AbstractSvtT0Shift> extends
+            BaseConditionsObjectCollection<T> {
 
         /**
          * Get the t0 shift associated with a given DAQ pair
@@ -37,7 +37,7 @@
      * @return the t0 shift
      */
     @Field(names = {"t0_shift"})
-    public final double getT0Shift() {
-        return getFieldValue("t0_shift");
+    public final Double getT0Shift() {
+        return this.getFieldValue("t0_shift");
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/CalibrationHandler.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/CalibrationHandler.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/CalibrationHandler.java	Wed Jul  8 14:47:40 2015
@@ -3,6 +3,7 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.hps.conditions.api.ConditionsObjectException;
 import org.hps.conditions.database.DatabaseConditionsManager;
 import org.hps.conditions.svt.SvtCalibration.SvtCalibrationCollection;
 import org.hps.conditions.svt.SvtChannel.SvtChannelCollection;
@@ -13,32 +14,37 @@
 import org.xml.sax.helpers.DefaultHandler;
 
 /**
- *  Handler for calibration events.
+ * Handler for calibration events.
  *
- *  @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Omar Moreno, UCSC
  */
 class CalibrationHandler extends DefaultHandler {
 
     /**
      * Initialize the logger.
      */
-    private static Logger logger = LogUtil.create(SvtConditionsLoader.class.getSimpleName(),
-            new DefaultLogFormatter(), Level.INFO);
+    private static Logger logger = LogUtil.create(SvtConditionsLoader.class.getSimpleName(), new DefaultLogFormatter(),
+            Level.INFO);
 
     /**
-     * List of SVT channels.
+     * Baseline sample ID (0-5).
      */
-    private SvtChannelCollection svtChannels;
-
-    /**
-     * List of SVT calibrations.
-     */
-    private SvtCalibrationCollection calibrations = new SvtCalibrationCollection();
+    private int baselineSampleID = 0;
 
     /**
      * An SVT calibration object encapsulating the baseline and noise values for a channel.
      */
     private SvtCalibration calibration = null;
+
+    /**
+     * List of SVT calibrations.
+     */
+    private final SvtCalibrationCollection calibrations = new SvtCalibrationCollection();
+
+    /**
+     * Channel number (0-639).
+     */
+    private int channel = 0;
 
     /**
      * The string content from parsing an XML calibration.
@@ -56,14 +62,10 @@
     private int hybridID = 0;
 
     /**
-     * Channel number (0-639).
+     * Flag denoting whether the calibrations of a given channel should be loaded into the conditions DB. If a channel
+     * is found to be missing baseline or noise values, is will be marked invalid.
      */
-    private int channel = 0;
-
-    /**
-     * Baseline sample ID (0-5).
-     */
-    private int baselineSampleID = 0;
+    private boolean isValidChannel = false;
 
     /**
      * Noise sample ID (0-5).
@@ -72,55 +74,29 @@
     private int noiseSampleID = 0;
 
     /**
-     * Flag denoting whether the calibrations of a given channel should be
-     * loaded into the conditions DB.  If a channel is found to be missing
-     * baseline or noise values, is will be marked invalid.
+     * List of SVT channels.
      */
-    private boolean isValidChannel = false;
+    private final SvtChannelCollection svtChannels;
 
     /**
      * Default constructor.
      */
     public CalibrationHandler() {
-       svtChannels = (SvtChannelCollection) DatabaseConditionsManager.getInstance()
-               .getCachedConditions(SvtChannelCollection.class, "svt_channels").getCachedData();
+        this.svtChannels = DatabaseConditionsManager.getInstance()
+                .getCachedConditions(SvtChannelCollection.class, "svt_channels").getCachedData();
     }
 
     /**
-     *  Method that is triggered when the start tag is encountered.
+     * Method called to extract character data inside of an element.
      *
-     *  @param uri the Namespace URI
-     *  @param locaName the local name (without prefix)
-     *  @param qName the qualified name (with prefix)
-     *  @param attributes the attributes attached to the element
-     *  @throws SAXException if there is an error processing the element
+     * @param ch the characters
+     * @param start the start position in the character array
+     * @param length the number of characters to use from the character array
+     * @throws SAXException if there is an error processing the element (possibly wraps another exception type)
      */
     @Override
-    public void startElement(final String uri, final String localName, final String qName, final Attributes attributes)
-            throws SAXException {
-
-        switch (qName) {
-            case "Feb":
-                febID = Integer.parseInt(attributes.getValue("id"));
-                break;
-            case "Hybrid":
-                hybridID = Integer.parseInt(attributes.getValue("id"));
-                logger.info("Processing calibrations for FEB " + febID + " Hybrid " + hybridID);
-                break;
-            case "channel":
-                channel = Integer.parseInt(attributes.getValue("id"));
-                calibration = new SvtCalibration(svtChannels.findChannelID(febID, hybridID, channel));
-                isValidChannel = false;
-                break;
-            case "baseline":
-                baselineSampleID = Integer.parseInt(attributes.getValue("id"));
-                break;
-            case "noise":
-                noiseSampleID = Integer.parseInt(attributes.getValue("id"));
-                break;
-            default:
-                break;
-        }
+    public void characters(final char[] ch, final int start, final int length) throws SAXException {
+        this.content = String.copyValueOf(ch, start, length).trim();
     }
 
     /**
@@ -132,41 +108,30 @@
      * @throws SAXException if there is an error processing the element
      */
     @Override
-    public void endElement(final String uri, final String localName, final String qName)
-            throws SAXException {
+    public void endElement(final String uri, final String localName, final String qName) throws SAXException {
 
         switch (qName) {
             case "channel":
-                if (isValidChannel) {
-                    calibrations.add(calibration);
+                if (this.isValidChannel) {
+                    try {
+                        this.calibrations.add(this.calibration);
+                    } catch (final ConditionsObjectException e) {
+                        throw new RuntimeException(e);
+                    }
                 }
                 break;
             case "baseline":
-                calibration.setPedestal(baselineSampleID, Double.parseDouble(content));
-                isValidChannel = true;
+                this.calibration.setPedestal(this.baselineSampleID, Double.parseDouble(this.content));
+                this.isValidChannel = true;
                 break;
             case "noise":
-                calibration.setNoise(baselineSampleID, Double.parseDouble(content));
-                isValidChannel = true;
+                this.calibration.setNoise(this.baselineSampleID, Double.parseDouble(this.content));
+                this.isValidChannel = true;
                 break;
             default:
                 break;
         }
     }
-
-   /**
-    * Method called to extract character data inside of an element.
-    *
-    * @param ch the characters
-    * @param start the start position in the character array
-    * @param length the number of characters to use from the character array
-    * @throws SAXException if there is an error processing the element (possibly wraps another exception type)
-    */
-   @Override
-   public void characters(final char[] ch, final int start, final int length)
-       throws SAXException {
-       content = String.copyValueOf(ch, start, length).trim();
-   }
 
     /**
      * Get the {@link SvtCalibrationCollection} created from parsing the XML input file.
@@ -174,6 +139,44 @@
      * @return the {@link SvtCalibrationCollection} created from parsing the XML
      */
     public SvtCalibrationCollection getCalibrations() {
-        return calibrations;
+        return this.calibrations;
+    }
+
+    /**
+     * Method that is triggered when the start tag is encountered.
+     *
+     * @param uri the Namespace URI
+     * @param locaName the local name (without prefix)
+     * @param qName the qualified name (with prefix)
+     * @param attributes the attributes attached to the element
+     * @throws SAXException if there is an error processing the element
+     */
+    @Override
+    public void startElement(final String uri, final String localName, final String qName, final Attributes attributes)
+            throws SAXException {
+
+        switch (qName) {
+            case "Feb":
+                this.febID = Integer.parseInt(attributes.getValue("id"));
+                break;
+            case "Hybrid":
+                this.hybridID = Integer.parseInt(attributes.getValue("id"));
+                logger.info("Processing calibrations for FEB " + this.febID + " Hybrid " + this.hybridID);
+                break;
+            case "channel":
+                this.channel = Integer.parseInt(attributes.getValue("id"));
+                this.calibration = new SvtCalibration(this.svtChannels.findChannelID(this.febID, this.hybridID,
+                        this.channel));
+                this.isValidChannel = false;
+                break;
+            case "baseline":
+                this.baselineSampleID = Integer.parseInt(attributes.getValue("id"));
+                break;
+            case "noise":
+                this.noiseSampleID = Integer.parseInt(attributes.getValue("id"));
+                break;
+            default:
+                break;
+        }
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/ChannelConstants.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/ChannelConstants.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/ChannelConstants.java	Wed Jul  8 14:47:40 2015
@@ -3,10 +3,15 @@
 /**
  * This class represents the combined conditions for a single SVT channel.
  *
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Omar Moreno, UCSC
+ * @author Jeremy McCormick, SLAC
  */
 public final class ChannelConstants {
+
+    /**
+     * Flag to indicate the channel is bad and should not be used for reconstruction.
+     */
+    private boolean badChannel = false;
 
     /**
      * The pedestal and noise for the channel.
@@ -24,14 +29,72 @@
     private SvtShapeFitParameters shapeFitParameters = null;
 
     /**
-     * Flag to indicate the channel is bad and should not be used for reconstruction.
-     */
-    private boolean badChannel = false;
-
-    /**
      * Class constructor.
      */
     ChannelConstants() {
+    }
+
+    /**
+     * Get the calibration.
+     *
+     * @return the calibration object
+     */
+    public SvtCalibration getCalibration() {
+        return this.calibration;
+    }
+
+    /**
+     * Get the gain.
+     *
+     * @return the gain object
+     */
+    public SvtGain getGain() {
+        return this.gain;
+    }
+
+    /**
+     * Get the shape fit parameters.
+     *
+     * @return the shape fit parameters
+     */
+    public SvtShapeFitParameters getShapeFitParameters() {
+        return this.shapeFitParameters;
+    }
+
+    /**
+     * Check if this is a bad channel.
+     *
+     * @return <code>true</code> if channel is bad
+     */
+    public boolean isBadChannel() {
+        return this.badChannel;
+    }
+
+    /**
+     * Set the bad channel flag.
+     *
+     * @param badChannel the bad channel flag value
+     */
+    void setBadChannel(final boolean badChannel) {
+        this.badChannel = badChannel;
+    }
+
+    /**
+     * Set the calibration.
+     *
+     * @param calibration the calibration object
+     */
+    void setCalibration(final SvtCalibration calibration) {
+        this.calibration = calibration;
+    }
+
+    /**
+     * Set the gain.
+     *
+     * @param gain the gain object
+     */
+    void setGain(final SvtGain gain) {
+        this.gain = gain;
     }
 
     /**
@@ -44,80 +107,18 @@
     }
 
     /**
-     * Set the gain.
-     *
-     * @param gain the gain object
-     */
-    void setGain(final SvtGain gain) {
-        this.gain = gain;
-    }
-
-    /**
-     * Set the calibration.
-     *
-     * @param calibration the calibration object
-     */
-    void setCalibration(final SvtCalibration calibration) {
-        this.calibration = calibration;
-    }
-
-    /**
-     * Set the bad channel flag.
-     *
-     * @param badChannel the bad channel flag value
-     */
-    void setBadChannel(final boolean badChannel) {
-        this.badChannel = badChannel;
-    }
-
-    /**
-     * Check if this is a bad channel.
-     *
-     * @return <code>true</code> if channel is bad
-     */
-    public boolean isBadChannel() {
-        return badChannel;
-    }
-
-    /**
-     * Get the shape fit parameters.
-     *
-     * @return the shape fit parameters
-     */
-    public SvtShapeFitParameters getShapeFitParameters() {
-        return shapeFitParameters;
-    }
-
-    /**
-     * Get the gain.
-     *
-     * @return the gain object
-     */
-    public SvtGain getGain() {
-        return gain;
-    }
-
-    /**
-     * Get the calibration.
-     *
-     * @return the calibration object
-     */
-    public SvtCalibration getCalibration() {
-        return calibration;
-    }
-
-    /**
      * Convert this object to a string.
      *
      * @return This object converted to a string.
      */
+    @Override
     public String toString() {
         final StringBuffer buffer = new StringBuffer();
-        buffer.append(getCalibration());
+        buffer.append(this.getCalibration());
         buffer.append(", ");
-        buffer.append(getGain());
+        buffer.append(this.getGain());
         buffer.append(", ");
-        buffer.append(getShapeFitParameters());
+        buffer.append(this.getShapeFitParameters());
         return buffer.toString();
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/DaqMapHandler.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/DaqMapHandler.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/DaqMapHandler.java	Wed Jul  8 14:47:40 2015
@@ -1,5 +1,6 @@
 package org.hps.conditions.svt;
 
+import org.hps.conditions.api.ConditionsObjectException;
 import org.hps.conditions.svt.SvtChannel.SvtChannelCollection;
 import org.hps.conditions.svt.SvtDaqMapping.SvtDaqMappingCollection;
 import org.xml.sax.Attributes;
@@ -9,7 +10,7 @@
 /**
  * Handler for DAQ map events.
  *
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Omar Moreno, UCSC
  */
 public final class DaqMapHandler extends DefaultHandler {
 
@@ -69,7 +70,11 @@
      */
     public void addSvtChannels(final int febID, final int febHybridID) {
         for (int channel = 0; channel < CHANNELS_MAX; channel++) {
-            this.svtChannels.add(new SvtChannel(this.currentSvtChannelID, this.febID, this.hybridID, channel));
+            try {
+                this.svtChannels.add(new SvtChannel(this.currentSvtChannelID, this.febID, this.hybridID, channel));
+            } catch (final ConditionsObjectException e) {
+                throw new RuntimeException(e);
+            }
             this.currentSvtChannelID++;
         }
     }
@@ -99,24 +104,28 @@
     public void endElement(final String uri, final String localName, final String qName) throws SAXException {
 
         switch (qName) {
-        case "Hybrid":
-            this.daqMap.add(this.daqMapping);
-            this.addSvtChannels(this.febID, this.hybridID);
-            break;
-        case "Half":
-            this.daqMapping.setSvtHalf(this.content);
-            break;
-        case "Layer":
-            this.daqMapping.setLayerNumber(Integer.parseInt(this.content));
-            break;
-        case "Side":
-            this.daqMapping.setSide(this.content);
-            break;
-        case "Orientation":
-            this.daqMapping.setOrientation(this.content);
-            break;
-        default:
-            break;
+            case "Hybrid":
+                try {
+                    this.daqMap.add(this.daqMapping);
+                } catch (final ConditionsObjectException e) {
+                    throw new RuntimeException(e);
+                }
+                this.addSvtChannels(this.febID, this.hybridID);
+                break;
+            case "Half":
+                this.daqMapping.setSvtHalf(this.content);
+                break;
+            case "Layer":
+                this.daqMapping.setLayerNumber(Integer.parseInt(this.content));
+                break;
+            case "Side":
+                this.daqMapping.setSide(this.content);
+                break;
+            case "Orientation":
+                this.daqMapping.setOrientation(this.content);
+                break;
+            default:
+                break;
         }
     }
 
@@ -152,15 +161,15 @@
             throws SAXException {
 
         switch (qName) {
-        case "Feb":
-            this.febID = Integer.parseInt(attributes.getValue("id"));
-            break;
-        case "Hybrid":
-            this.hybridID = Integer.parseInt(attributes.getValue("id"));
-            this.daqMapping = new SvtDaqMapping(this.febID, this.hybridID);
-            break;
-        default:
-            break;
+            case "Feb":
+                this.febID = Integer.parseInt(attributes.getValue("id"));
+                break;
+            case "Hybrid":
+                this.hybridID = Integer.parseInt(attributes.getValue("id"));
+                this.daqMapping = new SvtDaqMapping(this.febID, this.hybridID);
+                break;
+            default:
+                break;
         }
     }
 

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/MotorPositionLoader.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/MotorPositionLoader.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/MotorPositionLoader.java	Wed Jul  8 14:47:40 2015
@@ -19,20 +19,20 @@
 import org.apache.commons.cli.PosixParser;
 
 /**
- * Load SVT motor positions from a MYA dump, figure out time ranges (same position for > 10 seconds), and then 
- * convert the motor stage to an opening angle.
+ * Load SVT motor positions from a MYA dump, figure out time ranges (same position for > 10 seconds), and then convert
+ * the motor stage to an opening angle.
  * <p>
  * The calculated angle ranges are written out to a comma delimited text file with double-quoted field values.
  *
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
  */
 public class MotorPositionLoader {
 
     class MotorPositionInterval {
 
+        private final double angle;
         private final Date endDate;
         private final Date startDate;
-        private final double angle;
         private final double yStage;
 
         MotorPositionInterval(final Date startDate, final Date endDate, final double angle, final double yStage) {
@@ -42,24 +42,26 @@
             this.yStage = yStage;
         }
 
+        double getAngle() {
+            return this.angle;
+        }
+
         Date getEndDate() {
-            return endDate;
+            return this.endDate;
         }
 
         Date getStartDate() {
-            return startDate;
-        }
-
-        double getAngle() {
-            return angle;
-        }
-        
+            return this.startDate;
+        }
+
         double getYStage() {
-            return yStage;
-        }
-        
+            return this.yStage;
+        }
+
+        @Override
         public String toString() {
-            return "MotorPositionInterval { start: " + startDate + ", end: " + endDate + ", angle: " + angle + ", yStage: " + yStage + " }";
+            return "MotorPositionInterval { start: " + this.startDate + ", end: " + this.endDate + ", angle: "
+                    + this.angle + ", yStage: " + this.yStage + " }";
         }
     }
 
@@ -74,11 +76,11 @@
         }
 
         Date getDate() {
-            return date;
+            return this.date;
         }
 
         double getPosition() {
-            return position;
+            return this.position;
         }
     }
 
@@ -89,8 +91,8 @@
     private static final double ANGLE_CONVERSION = 832.714;
 
     private static final double BOTTOM_ANGLE_CONSTANT = 17.397;
-    //private static final double BOTTOM_LAYER_CONSTANT1 = 0.363;
-    //private static final double BOTTOM_LAYER_CONSTANT2 = -6.815;
+    // private static final double BOTTOM_LAYER_CONSTANT1 = 0.363;
+    // private static final double BOTTOM_LAYER_CONSTANT2 = -6.815;
 
     private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
@@ -99,8 +101,8 @@
     private static final Options OPTIONS = new Options();
 
     private static final double TOP_ANGLE_CONSTANT = 17.821;
-    //private static final double TOP_LAYER_CONSTANT1 = -0.391;
-    //private static final double TOP_LAYER_CONSTANT2 = 7.472;
+    // private static final double TOP_LAYER_CONSTANT1 = -0.391;
+    // private static final double TOP_LAYER_CONSTANT2 = 7.472;
 
     static {
         OPTIONS.addOption("h", "help", false, "print help");
@@ -109,82 +111,10 @@
         OPTIONS.addOption("i", "input-file", true, "input text file dumped from MYA (required)");
         OPTIONS.getOption("i").setRequired(true);
         OPTIONS.addOption("o", "output-file", true, "output text file with computed angle intervals");
-        //OPTIONS.addOption("l", "layer", false, "write out layer 1 position instead of computed angle");
-    }
-    
-    public void setSide(Side side) {
-        this.side = side;
-        if (Side.TOP.equals(side)) {
-            this.motorConstant = TOP_ANGLE_CONSTANT;
-            //this.layerConstant1 = TOP_LAYER_CONSTANT1;
-            //this.layerConstant2 = TOP_LAYER_CONSTANT2;
-        } else if (Side.BOT.equals(side)) {
-            this.motorConstant = BOTTOM_ANGLE_CONSTANT;
-            //this.layerConstant1 = BOTTOM_LAYER_CONSTANT1;
-            //this.layerConstant2 = BOTTOM_LAYER_CONSTANT2;
-        }
-    }
-        
-    /**
-     * Run from command line arguments.
-     * 
-     * @param args
-     */
-    void run(final String args[]) {
-        
-        final PosixParser parser = new PosixParser();
-        
-        CommandLine cl = null;        
-        try {
-            cl = parser.parse(OPTIONS, args);
-        } catch (final Exception e) {
-            printUsage(1);
-            throw new RuntimeException();
-        }
-
-        if (cl.hasOption("h")) {
-            printUsage(0);
-        }
-
-        if (cl.hasOption("s")) {
-            setSide(Side.valueOf(cl.getOptionValue("s").toUpperCase()));
-        } else {
-            printUsage(0);
-        }
-        
-        this.setSide(side);
-                
-        String path = null;
-        if (cl.hasOption("i")) {
-            path = cl.getOptionValue("i");
-        } else {
-            printUsage(1);
-        }
-
-        //if (cl.hasOption("l")) {
-        //    setWriteLayerPosition(true);
-        //}
-
-        try {
-            load(path);
-        } catch (final Exception e) {
-            throw new RuntimeException(e);
-        }
-
-        // Find the time intervals with a certain motor position setting.
-        findIntervals();
-
-        if (cl.hasOption("o")) {
-            final String outputPath = cl.getOptionValue("o");
-            try {
-                toCsv(outputPath);
-            } catch (final IOException e) {
-                throw new RuntimeException(e);
-            }
-        }
-    }
-
-    public static void main(final String args[]) {        
+        // OPTIONS.addOption("l", "layer", false, "write out layer 1 position instead of computed angle");
+    }
+
+    public static void main(final String args[]) {
         new MotorPositionLoader().run(args);
     }
 
@@ -199,49 +129,45 @@
 
     private List<MotorPositionInterval> intervals;
 
-    //private double layerConstant1;
-    //private double layerConstant2;
-
     private double motorConstant;
 
     private List<MotorPositionMyaRecord> records;
 
-    //private boolean writeLayerPosition = false;
-    
+    // private double layerConstant1;
+    // private double layerConstant2;
+
     Side side = null;
 
     MotorPositionLoader() {
     }
 
+    // private boolean writeLayerPosition = false;
+
     private double computeAngle(final double yStage) {
-        double angle = (motorConstant - yStage) / ANGLE_CONVERSION;
-        if (Side.BOT.equals(side)) {
+        double angle = (this.motorConstant - yStage) / ANGLE_CONVERSION;
+        if (Side.BOT.equals(this.side)) {
             angle = -angle;
         }
         return angle;
     }
 
-    //private double computeLayer1Position(final double yStage) {
-    //    return layerConstant1 * yStage + layerConstant2;
-    //}
-
     List<MotorPositionInterval> findIntervals() {
-        intervals = new ArrayList<MotorPositionInterval>();
-        for (int i = 0; i < records.size() - 1; i++) {
-            final Date currentDate = records.get(i).getDate();
-            final Date nextDate = records.get(i + 1).getDate();
+        this.intervals = new ArrayList<MotorPositionInterval>();
+        for (int i = 0; i < this.records.size() - 1; i++) {
+            final Date currentDate = this.records.get(i).getDate();
+            final Date nextDate = this.records.get(i + 1).getDate();
             final long timeDiff = nextDate.getTime() - currentDate.getTime();
             if (timeDiff >= MIN_TIME_INTERVAL) {
-                final double yStage = records.get(i).getPosition();
-                double angle = this.computeAngle(yStage);
-                intervals.add(new MotorPositionInterval(currentDate, nextDate, angle, yStage));
+                final double yStage = this.records.get(i).getPosition();
+                final double angle = this.computeAngle(yStage);
+                this.intervals.add(new MotorPositionInterval(currentDate, nextDate, angle, yStage));
             }
         }
-        return intervals;
+        return this.intervals;
     }
 
     void load(final String path) throws IOException, ParseException, FileNotFoundException {
-        records = new ArrayList<MotorPositionMyaRecord>();
+        this.records = new ArrayList<MotorPositionMyaRecord>();
         try (BufferedReader br = new BufferedReader(new FileReader(path))) {
             String line;
             while ((line = br.readLine()) != null) {
@@ -250,7 +176,7 @@
                 try {
                     final Date date = DATE_FORMAT.parse(dateString);
                     final double position = Double.parseDouble(positionString);
-                    records.add(new MotorPositionMyaRecord(date, position));
+                    this.records.add(new MotorPositionMyaRecord(date, position));
                 } catch (final NumberFormatException e) {
                     e.printStackTrace();
                 }
@@ -258,15 +184,91 @@
         }
     }
 
-    //private void setWriteLayerPosition(final boolean writeLayer) {
-    //    this.writeLayerPosition = writeLayer;
-    //}
+    // private double computeLayer1Position(final double yStage) {
+    // return layerConstant1 * yStage + layerConstant2;
+    // }
+
+    /**
+     * Run from command line arguments.
+     *
+     * @param args
+     */
+    void run(final String args[]) {
+
+        final PosixParser parser = new PosixParser();
+
+        CommandLine cl = null;
+        try {
+            cl = parser.parse(OPTIONS, args);
+        } catch (final Exception e) {
+            printUsage(1);
+            throw new RuntimeException();
+        }
+
+        if (cl.hasOption("h")) {
+            printUsage(0);
+        }
+
+        if (cl.hasOption("s")) {
+            this.setSide(Side.valueOf(cl.getOptionValue("s").toUpperCase()));
+        } else {
+            printUsage(0);
+        }
+
+        this.setSide(this.side);
+
+        String path = null;
+        if (cl.hasOption("i")) {
+            path = cl.getOptionValue("i");
+        } else {
+            printUsage(1);
+        }
+
+        // if (cl.hasOption("l")) {
+        // setWriteLayerPosition(true);
+        // }
+
+        try {
+            this.load(path);
+        } catch (final Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        // Find the time intervals with a certain motor position setting.
+        this.findIntervals();
+
+        if (cl.hasOption("o")) {
+            final String outputPath = cl.getOptionValue("o");
+            try {
+                this.toCsv(outputPath);
+            } catch (final IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public void setSide(final Side side) {
+        this.side = side;
+        if (Side.TOP.equals(side)) {
+            this.motorConstant = TOP_ANGLE_CONSTANT;
+            // this.layerConstant1 = TOP_LAYER_CONSTANT1;
+            // this.layerConstant2 = TOP_LAYER_CONSTANT2;
+        } else if (Side.BOT.equals(side)) {
+            this.motorConstant = BOTTOM_ANGLE_CONSTANT;
+            // this.layerConstant1 = BOTTOM_LAYER_CONSTANT1;
+            // this.layerConstant2 = BOTTOM_LAYER_CONSTANT2;
+        }
+    }
+
+    // private void setWriteLayerPosition(final boolean writeLayer) {
+    // this.writeLayerPosition = writeLayer;
+    // }
 
     private void toCsv(final String path) throws IOException {
-        System.out.println("writing " + intervals.size() + " intervals to file to " + path + " ...");
+        System.out.println("writing " + this.intervals.size() + " intervals to file to " + path + " ...");
         final FileWriter fw = new FileWriter(new File(path));
         final BufferedWriter bw = new BufferedWriter(fw);
-        for (final MotorPositionInterval interval : intervals) {
+        for (final MotorPositionInterval interval : this.intervals) {
             bw.write("\"" + DATE_FORMAT.format(interval.getStartDate()) + "\",");
             bw.write("\"" + DATE_FORMAT.format(interval.getEndDate()) + "\",");
             bw.write("\"" + interval.getAngle() + "\"");

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/OpeningAngleLoader.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/OpeningAngleLoader.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/OpeningAngleLoader.java	Wed Jul  8 14:47:40 2015
@@ -14,37 +14,91 @@
 import org.hps.conditions.svt.MotorPositionLoader.MotorPositionInterval;
 import org.hps.conditions.svt.MotorPositionLoader.Side;
 
+/**
+ * @author Jeremy McCormick, SLAC
+ */
 public class OpeningAngleLoader {
 
+    private static final String BOT_FILE = "mya_svt_bot.txt";
+    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MMMM dd YYYY HH:mm z");
+    private static final String OUT_FILE = "svt_opening_angles.txt";
+    private static final String RUN_FILE = "runs.csv";
+
     private static final String TOP_FILE = "mya_svt_top.txt";
-    private static final String BOT_FILE = "mya_svt_bot.txt";
-    private static final String RUN_FILE = "runs.csv";
-    private static final String OUT_FILE = "svt_opening_angles.txt";
-    
-    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MMMM dd YYYY HH:mm z");
-    
-    public static void main(String[] args) throws Exception {
-        
+
+    /**
+     * Check if the run record looks good.
+     *
+     * @param data
+     * @return
+     */
+    private static boolean acceptRun(final RunData data) {
+        return !data.getRecord().get("to_tape").equals("JUNK")
+                && data.getRecord().get("trigger_config").trim().length() > 0
+                && !data.getRecord().get("trigger_config").contains("cosmic") && data.getStartDate() != null;
+    }
+
+    private static MotorPositionInterval findInterval(final List<MotorPositionInterval> intervals, final Date date) {
+        MotorPositionInterval interval = null;
+        final Iterator<MotorPositionInterval> it = intervals.listIterator();
+        while ((interval = it.next()) != null) {
+
+            // Start and end dates in the interval.
+            final Date startDate = interval.getStartDate();
+            final Date endDate = interval.getEndDate();
+
+            // Check if given date is within the interval.
+            if ((startDate.compareTo(date) == -1 || startDate.compareTo(date) == 0) && endDate.compareTo(date) == 1
+                    || endDate.compareTo(date) == 0) {
+                break;
+            }
+
+            // Didn't find it.
+            if (!it.hasNext()) {
+                interval = null;
+                break;
+            }
+        }
+        return interval;
+    }
+
+    private static List<MotorPositionInterval> getMotorPositionIntervals(final String path, final Side side)
+            throws Exception {
+        final MotorPositionLoader loader = new MotorPositionLoader();
+        loader.setSide(side);
+        loader.load(path);
+        return loader.findIntervals();
+    }
+
+    private static RunMap loadRunMap(final String path) {
+        final File runFile = new File(path);
+        final RunSpreadsheet runSpreadsheet = new RunSpreadsheet(runFile);
+        return runSpreadsheet.getRunMap();
+    }
+
+    public static void main(final String[] args) throws Exception {
+
         // Load top and bottom intervals from MYA dump.
-        List<MotorPositionInterval> topIntervals = getMotorPositionIntervals(TOP_FILE, Side.TOP);
-        List<MotorPositionInterval> botIntervals = getMotorPositionIntervals(BOT_FILE, Side.BOT);
-        
+        final List<MotorPositionInterval> topIntervals = getMotorPositionIntervals(TOP_FILE, Side.TOP);
+        final List<MotorPositionInterval> botIntervals = getMotorPositionIntervals(BOT_FILE, Side.BOT);
+
         // Load run map from spreadsheet.
-        RunMap runMap = loadRunMap(RUN_FILE);
-        
+        final RunMap runMap = loadRunMap(RUN_FILE);
+
         // Write out run data combined with SVT opening angle intervals.
-        PrintStream ps = new PrintStream(new FileOutputStream(OUT_FILE));
+        final PrintStream ps = new PrintStream(new FileOutputStream(OUT_FILE));
         for (final RunData data : runMap.values()) {
             if (acceptRun(data)) {
                 final MotorPositionInterval topInterval = findInterval(topIntervals, data.getStartDate());
                 final MotorPositionInterval botInterval = findInterval(botIntervals, data.getStartDate());
                 printLine(ps, data, topInterval, botInterval);
             }
-        }        
+        }
         ps.close();
     }
-    
-    private static void printLine(PrintStream ps, RunData data, MotorPositionInterval topInterval, MotorPositionInterval botInterval) {
+
+    private static void printLine(final PrintStream ps, final RunData data, final MotorPositionInterval topInterval,
+            final MotorPositionInterval botInterval) {
         ps.print("run: " + data.getRun() + " @ [" + data.getRecord().get("svt_y_position") + "], ");
         if (topInterval != null) {
             ps.print("start(top): " + DATE_FORMAT.format(topInterval.getStartDate()) + ", ");
@@ -82,52 +136,4 @@
         ps.println();
         ps.flush();
     }
-    
-    private static List<MotorPositionInterval> getMotorPositionIntervals(String path, Side side) throws Exception {
-        MotorPositionLoader loader = new MotorPositionLoader();
-        loader.setSide(side);
-        loader.load(path);
-        return loader.findIntervals();
-    }
-
-    /**
-     * Check if the run record looks good.
-     * 
-     * @param data
-     * @return
-     */
-    private static boolean acceptRun(RunData data) {
-        return !data.getRecord().get("to_tape").equals("JUNK") && data.getRecord().get("trigger_config").trim().length() > 0
-                && !data.getRecord().get("trigger_config").contains("cosmic") && data.getStartDate() != null;
-    }
-    
-    private static RunMap loadRunMap(String path) {
-        final File runFile = new File(path);
-        final RunSpreadsheet runSpreadsheet = new RunSpreadsheet(runFile);
-        return runSpreadsheet.getRunMap();
-    }
-
-    private static MotorPositionInterval findInterval(List<MotorPositionInterval> intervals, Date date) {
-        MotorPositionInterval interval = null;
-        Iterator<MotorPositionInterval> it = intervals.listIterator();
-        while ((interval = it.next()) != null) {
-                
-            // Start and end dates in the interval.
-            Date startDate = interval.getStartDate();
-            Date endDate = interval.getEndDate();
-
-            // Check if given date is within the interval.
-            if ((startDate.compareTo(date) == -1 || startDate.compareTo(date) == 0) && endDate.compareTo(date) == 1
-                    || endDate.compareTo(date) == 0) {
-                break;
-            }
-                
-            // Didn't find it.
-            if (!it.hasNext()) {
-                interval = null;
-                break;
-            }            
-        }
-        return interval;
-    }   
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtAlignmentConstant.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtAlignmentConstant.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtAlignmentConstant.java	Wed Jul  8 14:47:40 2015
@@ -12,6 +12,7 @@
  * translation or rotation of a detector component.
  * <p>
  * The format of the keys is ABCDE where:<br>
+ * 
  * <pre>
  * A == half == [1,2]
  * B == alignment type == [1,2]
@@ -21,7 +22,7 @@
  * <p>
  * The key naming conventions are from the <a href="http://www.desy.de/~blobel/mptalks.html">Millipede</a> package.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 @Table(names = "svt_alignments")
 @Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_UPDATED)
@@ -32,16 +33,22 @@
      */
     @SuppressWarnings("serial")
     public static class SvtAlignmentConstantCollection extends BaseConditionsObjectCollection<SvtAlignmentConstant> {
-        
-        public SvtAlignmentConstant find(int id) {
-            for (SvtAlignmentConstant constant : this) {
+
+        /**
+         * Find an alignment constant by its parameter ID.
+         * 
+         * @param id the parameter ID
+         * @return the first object with matching parameter ID or <code>null</code> if not found
+         */
+        public SvtAlignmentConstant find(final int id) {
+            for (final SvtAlignmentConstant constant : this) {
                 if (constant.getParameter().equals(id)) {
                     return constant;
                 }
             }
             return null;
         }
-        
+
     };
 
     /**
@@ -49,10 +56,9 @@
      *
      * @return the alignment constant's key
      */
-    @Field(names = { "parameter" })
+    @Field(names = {"parameter"})
     public Integer getParameter() {
-        //System.out.println("parameter = " + this.getFieldValues().get("parameter") + "; type = " + this.getFieldValues().get("parameter").getClass());
-        return getFieldValue("parameter");
+        return this.getFieldValue("parameter");
     }
 
     /**
@@ -60,9 +66,9 @@
      *
      * @return the alignment constant's value as a double
      */
-    @Field(names = { "value" })
+    @Field(names = {"value"})
     public Double getValue() {
-        return getFieldValue("value");
+        return this.getFieldValue("value");
     }
 
     /**

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtBadChannel.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtBadChannel.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtBadChannel.java	Wed Jul  8 14:47:40 2015
@@ -2,20 +2,16 @@
 
 import org.hps.conditions.api.BaseConditionsObject;
 import org.hps.conditions.api.BaseConditionsObjectCollection;
-import org.hps.conditions.database.Converter;
 import org.hps.conditions.database.Field;
-import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
 
 /**
- * Represents a channel that has been flagged as bad, which should not
- * be used for physics reconstructions.  This might be done if the
- * channel is extremely noisy, etc.
+ * Represents a channel that has been flagged as bad, which should not be used for physics reconstructions. This might
+ * be done if the channel is extremely noisy, etc.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 @Table(names = {"svt_bad_channels", "test_run_svt_bad_channels"})
-@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED)
 public final class SvtBadChannel extends BaseConditionsObject {
 
     /**
@@ -27,19 +23,21 @@
 
     /**
      * Get the channel ID.
+     *
      * @return the channel ID
      */
     @Field(names = {"svt_channel_id"})
-    public int getChannelId() {
-        return getFieldValue("svt_channel_id");
+    public Integer getChannelId() {
+        return this.getFieldValue("svt_channel_id");
     }
 
     /**
      * Get a note about the bad channel.
+     *
      * @return a note about the bad channel
      */
     @Field(names = {"notes"})
-    public int getNote() {
-        return getFieldValue("notes");
+    public Integer getNote() {
+        return this.getFieldValue("notes");
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtBiasConditionsLoader.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtBiasConditionsLoader.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtBiasConditionsLoader.java	Wed Jul  8 14:47:40 2015
@@ -272,42 +272,36 @@
 
     private static final void loadToConditionsDB(List<SvtBiasRunRange> ranges) {
         logger.info("Load to DB...");
-        
+
         // Create a new collection for each run
         List<Integer> runsadded = new ArrayList<Integer>();
-        
-        
-        
-        
-        for(SvtBiasRunRange range : ranges) {
+
+        for (SvtBiasRunRange range : ranges) {
             logger.info("Loading " + range.toString());
             RunData rundata = range.getRun();
-            if(runsadded.contains(rundata.getRun())) {
+            if (runsadded.contains(rundata.getRun())) {
                 logger.warning("Run " + Integer.toString(rundata.getRun()) + " was already added?");
                 throw new RuntimeException("Run " + Integer.toString(rundata.getRun()) + " was already added?");
             }
             runsadded.add(rundata.getRun());
 
-            if(range.getRanges().isEmpty()) {
+            if (range.getRanges().isEmpty()) {
                 logger.info("No bias range for run " + range.getRun().getRun());
                 continue;
             }
-            
+
+            // create a collection
+            SvtBiasConstantCollection collection = new SvtBiasConstantCollection();
+
             int collectionId = -1;
             try {
-                collectionId = MANAGER.addCollection("svt_bias_constants", "whatever that is fine","run ranges for SVT HV bias ON");
+                collectionId = MANAGER.getCollectionId(collection, "run ranges for SVT HV bias ON");
             } catch (SQLException e1) {
-               throw new RuntimeException(e1);
-            }
-            
-            //create a collection
-            SvtBiasConstantCollection collection = new SvtBiasConstantCollection();
-            try {
-                collection.setCollectionId(collectionId);
-            } catch (ConditionsObjectException e1) {
-                throw new RuntimeException("cant set collection id",e1);
-            }
-            
+                throw new RuntimeException(e1);
+            }
+
+            collection.setCollectionId(collectionId);
+
             final ConditionsRecord condition = new ConditionsRecord();
             condition.setFieldValue("run_start", rundata.getRun());
             condition.setFieldValue("run_end", rundata.getRun());
@@ -315,39 +309,30 @@
             condition.setFieldValue("table_name", "svt_bias_constants");
             condition.setFieldValue("notes", "constants from mya");
             condition.setFieldValue("created", new Date());
-            condition.setFieldValue("created_by", System.getProperty("user.name"));            
+            condition.setFieldValue("created_by", System.getProperty("user.name"));
             condition.setFieldValue("collection_id", collectionId);
-            
-            for (SvtBiasMyaRange biasRange : range.getRanges()) {
-                //create a constant and add to the collection
-                final SvtBiasConstant constant = new SvtBiasConstant();
-                constant.setFieldValue("start", biasRange.getStartDate());
-                constant.setFieldValue("end", biasRange.getEndDate());
-                constant.setFieldValue("value", biasRange.getStart().getValue());
-                collection.add(constant);
+
+            try {
+
+                for (SvtBiasMyaRange biasRange : range.getRanges()) {
+                    // create a constant and add to the collection
+                    final SvtBiasConstant constant = new SvtBiasConstant();
+                    constant.setFieldValue("start", biasRange.getStartDate());
+                    constant.setFieldValue("end", biasRange.getEndDate());
+                    constant.setFieldValue("value", biasRange.getStart().getValue());
+                    collection.add(constant);
+                    logger.info(condition.toString());
+                }
                 
-                logger.info(condition.toString());
-            }
-
-
-            try {
-                try {
-                    collection.insert();
-                } catch (SQLException e) {
-                    throw new RuntimeException("cant instert collection", e);
-                }
+                // Insert collection data.
+                collection.insert();
+                
+                // Insert conditions record.
                 condition.insert();
 
-            } catch (ConditionsObjectException e) {
+            } catch (Exception e) {
                 throw new RuntimeException(e);
             }
-            
-        }
-
-
-    }
-    
-   
-    
-
+        }
+    }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtCalibration.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtCalibration.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtCalibration.java	Wed Jul  8 14:47:40 2015
@@ -1,4 +1,6 @@
 package org.hps.conditions.svt;
+
+import static org.hps.conditions.svt.AbstractSvtChannel.MAX_NUMBER_OF_SAMPLES;
 
 import org.hps.conditions.api.BaseConditionsObject;
 import org.hps.conditions.api.BaseConditionsObjectCollection;
@@ -7,13 +9,11 @@
 import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
 
-import static org.hps.conditions.svt.SvtChannel.MAX_NUMBER_OF_SAMPLES;
-
 /**
  * This class encapsulates noise and pedestal measurement for an SVT channel.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Jeremy McCormick, SLAC
+ * @author Omar Moreno, UCSC
  */
 @Table(names = {"svt_calibrations", "test_run_svt_calibrations"})
 @Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_UPDATED)
@@ -38,7 +38,7 @@
      * @param channelID the SVT channel ID
      */
     public SvtCalibration(final int channelID) {
-       this.setChannelID(channelID);
+        this.setChannelID(channelID);
     }
 
     /**
@@ -47,8 +47,8 @@
      * @return The channel ID
      */
     @Field(names = {"svt_channel_id"})
-    public int getChannelID() {
-        return getFieldValue("svt_channel_id");
+    public Integer getChannelID() {
+        return this.getFieldValue("svt_channel_id");
     }
 
     /**
@@ -58,11 +58,11 @@
      * @return the noise value
      */
     @Field(names = {"noise_0", "noise_1", "noise_2", "noise_3", "noise_4", "noise_5"})
-    public double getNoise(final int sample) {
+    public Double getNoise(final int sample) {
         if (sample < 0 || sample > MAX_NUMBER_OF_SAMPLES) {
             throw new IllegalArgumentException("Sample number is not within range.");
         }
-        return getFieldValue(Double.class, "noise_" + Integer.toString(sample));
+        return this.getFieldValue(Double.class, "noise_" + Integer.toString(sample));
     }
 
     /**
@@ -72,11 +72,11 @@
      * @return The pedestal value.
      */
     @Field(names = {"pedestal_0", "pedestal_1", "pedestal_2", "pedestal_3", "pedestal_4", "pedestal_5"})
-    public double getPedestal(final int sample) {
+    public Double getPedestal(final int sample) {
         if (sample < 0 || sample > MAX_NUMBER_OF_SAMPLES) {
             throw new IllegalArgumentException("Sample number is not within range.");
         }
-        return getFieldValue(Double.class, "pedestal_" + Integer.toString(sample));
+        return this.getFieldValue(Double.class, "pedestal_" + Integer.toString(sample));
     }
 
     /**
@@ -116,6 +116,7 @@
      * @return This object converted to a string.
      */
     // FIXME: This is a mess when it prints to console.
+    @Override
     public String toString() {
         final StringBuffer buffer = new StringBuffer();
         buffer.append("Channel ID: " + this.getChannelID());

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtChannel.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtChannel.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtChannel.java	Wed Jul  8 14:47:40 2015
@@ -4,77 +4,18 @@
 import java.util.Collection;
 import java.util.List;
 
-import org.hps.conditions.database.Converter;
 import org.hps.conditions.database.Field;
-import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
 import org.hps.util.Pair;
 
 /**
  * This class represents SVT channel setup information, including FEB ID, FEB Hybrid ID, and channel numbers.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Jeremy McCormick, SLAC
+ * @author Omar Moreno, UCSC
  */
-@Table(names = { "svt_channels" })
-@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED)
+@Table(names = {"svt_channels"})
 public final class SvtChannel extends AbstractSvtChannel {
-
-    /**
-     * Maximum channel number.
-     */
-    private static final int MAX_CHANNEL = 639;
-
-    /**
-     * Minimum channel number.
-     */
-    private static final int MIN_CHANNEL = 0;
-
-    /**
-     * Maximum FEB Hybrid ID.
-     */
-    private static final int MAX_FEB_HYBRID_ID = 3;
-
-    /**
-     * Minimum FEB hybrid ID.
-     */
-    private static final int MIN_FEB_HYBRID_ID = 0;
-
-    /**
-     * Maximum FEB ID.
-     */
-    private static final int MAX_FEB_ID = 9;
-
-    /**
-     * Minimum FEB ID.
-     */
-    private static final int MIN_FEB_ID = 0;
-
-    /**
-     * Default constructor.
-     */
-    public SvtChannel() {
-    }
-
-    /**
-     * Fully qualified constructor.
-     *
-     * @param channelID the SVT channel ID
-     * @param febID the Front End Board (FEB) ID (0-9)
-     * @param febHybridID the hybrid ID (0-3)
-     * @param channel the channel number (0-639)
-     */
-    public SvtChannel(final int channelID, final int febID, final int febHybridID, final int channel) {
-        if (!this.isValidFeb(febID)
-                || !this.isValidFebHybridID(febHybridID)
-                || !this.isValidPhysicalChannel(channel)) {
-            throw new RuntimeException("Invalid FEB ID, FEB hybrid ID or physical channel number is being used.");
-        }
-        this.setChannelID(channelID);
-        this.setFebID(febID);
-        this.setFebHybridID(febHybridID);
-        this.setChannel(channel);
-    }
 
     /**
      * Collection implementation for {@link SvtChannel}.
@@ -92,7 +33,7 @@
             final List<SvtChannel> channels = new ArrayList<SvtChannel>();
             final int febID = pair.getFirstElement();
             final int febHybridID = pair.getSecondElement();
-            for (SvtChannel channel : this) {
+            for (final SvtChannel channel : this) {
                 if (channel.getFebID() == febID && channel.getFebHybridID() == febHybridID) {
                     channels.add(channel);
                 }
@@ -122,23 +63,137 @@
     }
 
     /**
+     * Maximum channel number.
+     */
+    private static final int MAX_CHANNEL = 639;
+
+    /**
+     * Maximum FEB Hybrid ID.
+     */
+    private static final int MAX_FEB_HYBRID_ID = 3;
+
+    /**
+     * Maximum FEB ID.
+     */
+    private static final int MAX_FEB_ID = 9;
+
+    /**
+     * Minimum channel number.
+     */
+    private static final int MIN_CHANNEL = 0;
+
+    /**
+     * Minimum FEB hybrid ID.
+     */
+    private static final int MIN_FEB_HYBRID_ID = 0;
+
+    /**
+     * Minimum FEB ID.
+     */
+    private static final int MIN_FEB_ID = 0;
+
+    /**
+     * Default constructor.
+     */
+    public SvtChannel() {
+    }
+
+    /**
+     * Fully qualified constructor.
+     *
+     * @param channelID the SVT channel ID
+     * @param febID the Front End Board (FEB) ID (0-9)
+     * @param febHybridID the hybrid ID (0-3)
+     * @param channel the channel number (0-639)
+     */
+    public SvtChannel(final int channelID, final int febID, final int febHybridID, final int channel) {
+        if (!this.isValidFeb(febID) || !this.isValidFebHybridID(febHybridID) || !this.isValidPhysicalChannel(channel)) {
+            throw new RuntimeException("Invalid FEB ID, FEB hybrid ID or physical channel number is being used.");
+        }
+        this.setChannelID(channelID);
+        this.setFebID(febID);
+        this.setFebHybridID(febHybridID);
+        this.setChannel(channel);
+    }
+
+    /**
+     * Implementation of equals.
+     *
+     * @return <code>true</code> if the object equals this one
+     */
+    @Override
+    public boolean equals(final Object o) {
+        if (o == null) {
+            return false;
+        }
+        if (!(o instanceof SvtChannel)) {
+            return false;
+        }
+        if (o == this) {
+            return true;
+        }
+        final SvtChannel channel = (SvtChannel) o;
+        return this.getChannelID() == channel.getChannelID() && this.getFebID() == channel.getFebID()
+                && this.getFebHybridID() == channel.getFebHybridID() && this.getChannel() == channel.getChannel();
+    }
+
+    /**
+     * Get the FEB hybrid ID associated with this SVT channel ID.
+     *
+     * @return The FEB hybrid ID.
+     */
+    @Field(names = {"feb_hybrid_id"})
+    public Integer getFebHybridID() {
+        return this.getFieldValue("feb_hybrid_id");
+    }
+
+    /**
      * Get the FEB ID associated with this SVT channel ID.
      *
      * @return The FEB ID.
      */
-    @Field(names = { "feb_id" })
-    public int getFebID() {
-        return getFieldValue("feb_id");
-    }
-
-    /**
-     * Get the FEB hybrid ID associated with this SVT channel ID.
-     *
-     * @return The FEB hybrid ID.
-     */
-    @Field(names = { "feb_hybrid_id" })
-    public int getFebHybridID() {
-        return getFieldValue("feb_hybrid_id");
+    @Field(names = {"feb_id"})
+    public Integer getFebID() {
+        return this.getFieldValue("feb_id");
+    }
+
+    /**
+     * Checks if a FEB ID is valid.
+     *
+     * @param febID the Front End Board (FEB) ID
+     * @return <code>true</code> if the FEB ID lies within the range 0-9
+     */
+    public boolean isValidFeb(final int febID) {
+        return febID >= MIN_FEB_ID && febID <= MAX_FEB_ID ? true : false;
+    }
+
+    /**
+     * Checks if a Front End Board hybrid ID is valid.
+     *
+     * @param febHybridID the hybrid ID
+     * @return <code>true</code> if the hybrid ID lies within the range 0-3
+     */
+    public boolean isValidFebHybridID(final int febHybridID) {
+        return febHybridID >= MIN_FEB_HYBRID_ID && febHybridID <= MAX_FEB_HYBRID_ID ? true : false;
+    }
+
+    /**
+     * Checks if a physical channel number is valid.
+     *
+     * @param channel the physical channel number
+     * @return <code>true</code> if the channel number lies within the range 0-639
+     */
+    public boolean isValidPhysicalChannel(final int channel) {
+        return channel >= MIN_CHANNEL && channel <= MAX_CHANNEL ? true : false;
+    }
+
+    /**
+     * Set the FEB hybrid ID associated with this SVT channel ID.
+     *
+     * @param febHybridID : The FEB hybrid ID
+     */
+    public void setFebHybridID(final int febHybridID) {
+        this.setFieldValue("feb_hybrid_id", febHybridID);
     }
 
     /**
@@ -149,63 +204,4 @@
     public void setFebID(final int febID) {
         this.setFieldValue("feb_id", febID);
     }
-
-    /**
-     *  Set the FEB hybrid ID associated with this SVT channel ID.
-     *
-     *  @param febHybridID : The FEB hybrid ID
-     */
-    public void setFebHybridID(final int febHybridID) {
-        this.setFieldValue("feb_hybrid_id", febHybridID);
-    }
-
-    /**
-     * Checks if a FEB ID is valid.
-     *
-     * @param febID the Front End Board (FEB) ID
-     * @return <code>true</code> if the FEB ID lies within the range 0-9
-     */
-    public boolean isValidFeb(int febID) {
-        return (febID >= MIN_FEB_ID && febID <= MAX_FEB_ID) ? true : false;
-    }
-    
-    /**
-     * Checks if a Front End Board hybrid ID is valid.
-     *
-     * @param febHybridID the hybrid ID
-     * @return <code>true</code> if the hybrid ID lies within the range 0-3
-     */
-    public boolean isValidFebHybridID(int febHybridID) {
-        return (febHybridID >= MIN_FEB_HYBRID_ID && febHybridID <= MAX_FEB_HYBRID_ID) ? true : false; 
-    }
-    
-    /**
-     * Checks if a physical channel number is valid.
-     *
-     * @param channel the physical channel number
-     * @return <code>true</code> if the channel number lies within the range 0-639
-     */
-    public boolean isValidPhysicalChannel(int channel) {
-        return (channel >= MIN_CHANNEL && channel <= MAX_CHANNEL) ? true : false; 
-    }
-
-    /**
-     * Implementation of equals.
-     *
-     * @return <code>true</code> if the object equals this one
-     */
-    public boolean equals(Object o) {
-        if (o == null) {
-            return false;
-        }
-        if (!(o instanceof SvtChannel)) {
-            return false;
-        }
-        if (o == this) {
-            return true;
-        }
-        final SvtChannel channel = (SvtChannel) o;
-        return getChannelID() == channel.getChannelID() && getFebID() == channel.getFebID() 
-                && getFebHybridID() == channel.getFebHybridID() && getChannel() == channel.getChannel();
-    }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditions.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditions.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditions.java	Wed Jul  8 14:47:40 2015
@@ -6,14 +6,12 @@
 import org.hps.conditions.svt.SvtDaqMapping.SvtDaqMappingCollection;
 import org.hps.conditions.svt.SvtT0Shift.SvtT0ShiftCollection;
 
-// TODO: Move all constants to their own class
-
 /**
  * This class contains all test run SVT conditions data by readout channel. {@link SvtChannel} objects from the SVT
  * channel map can be used to lookup the conditions for individual channels.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Jeremy McCormick, SLAC
+ * @author Omar Moreno, UCSC
  */
 public final class SvtConditions extends AbstractSvtConditions {
 
@@ -117,7 +115,7 @@
         for (final SvtChannel channel : this.getChannelMap()) {
 
             // Get the conditions for the channel.
-            final ChannelConstants constants = getChannelConstants(channel);
+            final ChannelConstants constants = this.getChannelConstants(channel);
             final SvtGain gain = constants.getGain();
             final SvtShapeFitParameters shapeFit = constants.getShapeFitParameters();
             final SvtCalibration calibration = constants.getCalibration();
@@ -153,7 +151,7 @@
         buff.append("Printing SVT DAQ Map...");
         buff.append('\n');
         buff.append('\n');
-        buff.append(getDaqMap());
+        buff.append(this.getDaqMap());
 
         return buff.toString();
     }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsConverter.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsConverter.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsConverter.java	Wed Jul  8 14:47:40 2015
@@ -7,11 +7,11 @@
 import org.lcsim.conditions.ConditionsManager;
 
 /**
- * This class creates an {@link SvtConditions} object from the database, based
- * on the current run number known by the conditions manager.
+ * This class creates an {@link SvtConditions} object from the database, based on the current run number known by the
+ * conditions manager.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Jeremy McCormick, SLAC
+ * @author Omar Moreno, UCSC
  */
 public final class SvtConditionsConverter extends AbstractSvtConditionsConverter<SvtConditions> {
 
@@ -34,30 +34,31 @@
         final DatabaseConditionsManager dbConditionsManager = (DatabaseConditionsManager) manager;
 
         // Get the channel map from the conditions database
-        final SvtChannelCollection channels = dbConditionsManager.getCachedConditions(
-                SvtChannelCollection.class, "svt_channels").getCachedData();
+        final SvtChannelCollection channels = dbConditionsManager.getCachedConditions(SvtChannelCollection.class,
+                "svt_channels").getCachedData();
 
         // Create the SVT conditions object to use to encapsulate SVT condition
         // collections
-        conditions.setChannelMap(channels);
+        this.conditions.setChannelMap(channels);
 
         // Get the DAQ map from the conditions database
-        final SvtDaqMappingCollection daqMap = dbConditionsManager.getCachedConditions(
-                SvtDaqMappingCollection.class, "svt_daq_map").getCachedData();
-        conditions.setDaqMap(daqMap);
+        final SvtDaqMappingCollection daqMap = dbConditionsManager.getCachedConditions(SvtDaqMappingCollection.class,
+                "svt_daq_map").getCachedData();
+        this.conditions.setDaqMap(daqMap);
 
         // Get the collection of T0 shifts from the conditions database
-        final SvtT0ShiftCollection t0Shifts = dbConditionsManager.getCachedConditions(
-                SvtT0ShiftCollection.class, "svt_t0_shifts").getCachedData();
-        conditions.setT0Shifts(t0Shifts);
+        final SvtT0ShiftCollection t0Shifts = dbConditionsManager.getCachedConditions(SvtT0ShiftCollection.class,
+                "svt_t0_shifts").getCachedData();
+        this.conditions.setT0Shifts(t0Shifts);
 
-        conditions = super.getData(manager, name);
+        this.conditions = super.getData(manager, name);
 
-        return conditions;
+        return this.conditions;
     }
 
     /**
      * Get the type handled by this converter.
+     *
      * @return The type handled by this converter.
      */
     @Override

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsLoader.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsLoader.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsLoader.java	Wed Jul  8 14:47:40 2015
@@ -11,8 +11,8 @@
 import org.apache.commons.cli.ParseException;
 import org.apache.commons.cli.PosixParser;
 import org.hps.conditions.api.ConditionsRecord;
+import org.hps.conditions.api.TableMetaData;
 import org.hps.conditions.database.DatabaseConditionsManager;
-import org.hps.conditions.database.TableMetaData;
 import org.hps.conditions.svt.SvtCalibration.SvtCalibrationCollection;
 import org.hps.conditions.svt.SvtChannel.SvtChannelCollection;
 import org.hps.conditions.svt.SvtDaqMapping.SvtDaqMappingCollection;
@@ -23,7 +23,7 @@
 /**
  * Command line tool used to load SVT conditions into the conditions database.
  *
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Omar Moreno, UCSC
  */
 public final class SvtConditionsLoader {
 
@@ -119,9 +119,7 @@
                 calibrations.setTableMetaData(tableMetaData);
 
                 // Set the collection ID.
-                final int collectionID = DatabaseConditionsManager.getInstance().addCollection(
-                        SvtConditionsLoader.CALIBRATIONS_TABLE_NAME,
-                        "added with SvtConditionsLoader by " + System.getProperty("user.name"), null);
+                final int collectionID = DatabaseConditionsManager.getInstance().getCollectionId(calibrations, null);
                 calibrations.setCollectionId(collectionID);
                 logger.info("Using collection ID " + collectionID);
 
@@ -159,9 +157,7 @@
                 daqMapping.setTableMetaData(tableMetaData);
 
                 // Set the collection ID
-                int collectionID = DatabaseConditionsManager.getInstance().addCollection(
-                        SvtConditionsLoader.DAQ_MAP_TABLE_NAME,
-                        "added with SvtConditionsLoader by " + System.getProperty("user.name"), null);
+                int collectionID = DatabaseConditionsManager.getInstance().getCollectionId(daqMapping, null);
                 daqMapping.setCollectionId(collectionID);
                 logger.info("Using collection ID " + collectionID);
 
@@ -186,9 +182,7 @@
                 svtChannels.setTableMetaData(tableMetaData);
 
                 // Set the collection ID
-                collectionID = DatabaseConditionsManager.getInstance().addCollection(
-                        SvtConditionsLoader.SVT_CHANNELS_TABLE_NAME,
-                        "added with SvtConditionsLoader by " + System.getProperty("user.name"), null);
+                collectionID = DatabaseConditionsManager.getInstance().getCollectionId(svtChannels, null);
                 svtChannels.setCollectionId(collectionID);
                 logger.info("Using collection ID " + collectionID);
 

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsReader.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsReader.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsReader.java	Wed Jul  8 14:47:40 2015
@@ -12,7 +12,7 @@
 /**
  * Reader used to parse SVT conditions.
  *
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Omar Moreno, UCSC
  */
 public final class SvtConditionsReader {
 

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConfiguration.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConfiguration.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConfiguration.java	Wed Jul  8 14:47:40 2015
@@ -20,9 +20,9 @@
 /**
  * This class is the conditions object model for an SVT configuration saved into the database.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
-@Table(names = { "svt_configurations" })
+@Table(names = {"svt_configurations"})
 @Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_UPDATED)
 public final class SvtConfiguration extends BaseConditionsObject {
 
@@ -34,13 +34,18 @@
     }
 
     /**
-     * Get the filename associated with this configuration.
+     * Convert the raw database content for the configuration into an XML document.
      *
-     * @return The filename associated with the configuration.
+     * @return The Document created from the raw data.
+     * @throws IOException if there is an IO error
+     * @throws JDOMException is there is an XML parsing error
      */
-    @Field(names = { "filename" })
-    public String getFileName() {
-        return getFieldValue("filename");
+    public Document createDocument() throws IOException, JDOMException {
+        final byte[] bytes = this.getFieldValue("content");
+        final InputStream inputStream = new ByteArrayInputStream(bytes);
+        final SAXBuilder builder = new SAXBuilder();
+        builder.setValidation(false);
+        return builder.build(inputStream);
     }
 
     /**
@@ -48,24 +53,32 @@
      *
      * @return the content of the XML file as a byte array
      */
-    @Field(names = { "content" })
+    @Field(names = {"content"})
     public byte[] getContent() {
-        return getFieldValue("content");
+        return this.getFieldValue("content");
     }
 
     /**
-     * Convert the raw database content for the configuration into an XML document.
+     * Get the filename associated with this configuration.
      *
-     * @return The Document created from the raw data.
-     * @throws IOException if there is an IO error
-     * @throws JDOMException is there is an XML parsing error
+     * @return The filename associated with the configuration.
      */
-    public Document createDocument() throws IOException, JDOMException {
-        final byte[] bytes = getFieldValue("content");
-        final InputStream inputStream = new ByteArrayInputStream(bytes);
-        final SAXBuilder builder = new SAXBuilder();
-        builder.setValidation(false);
-        return builder.build(inputStream);
+    @Field(names = {"filename"})
+    public String getFileName() {
+        return this.getFieldValue("filename");
+    }
+
+    /**
+     * Save this configuration to a local file on disk using its name from the database.
+     */
+    public void writeToFile() {
+        final XMLOutputter out = new XMLOutputter();
+        out.setFormat(Format.getPrettyFormat());
+        try {
+            out.output(this.createDocument(), new FileWriter(this.getFileName()));
+        } catch (IOException | JDOMException e) {
+            throw new RuntimeException(e);
+        }
     }
 
     /**
@@ -77,20 +90,7 @@
         final XMLOutputter out = new XMLOutputter();
         out.setFormat(Format.getPrettyFormat());
         try {
-            out.output(createDocument(), new FileWriter(filename));
-        } catch (IOException | JDOMException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Save this configuration to a local file on disk using its name from the database.
-     */
-    public void writeToFile() {
-        final XMLOutputter out = new XMLOutputter();
-        out.setFormat(Format.getPrettyFormat());
-        try {
-            out.output(createDocument(), new FileWriter(getFileName()));
+            out.output(this.createDocument(), new FileWriter(filename));
         } catch (IOException | JDOMException e) {
             throw new RuntimeException(e);
         }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtDaqMapping.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtDaqMapping.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtDaqMapping.java	Wed Jul  8 14:47:40 2015
@@ -1,8 +1,6 @@
 package org.hps.conditions.svt;
 
-import org.hps.conditions.database.Converter;
 import org.hps.conditions.database.Field;
-import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
 import org.hps.util.Pair;
 import org.lcsim.detector.tracker.silicon.HpsSiSensor;
@@ -10,11 +8,10 @@
 /**
  * This class encapsulates the SVT DAQ map.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Jeremy McCormick, SLAC
+ * @author Omar Moreno, UCSC
  */
-@Table(names = { "svt_daq_map" })
-@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED)
+@Table(names = {"svt_daq_map"})
 public class SvtDaqMapping extends AbstractSvtDaqMapping {
 
     /**
@@ -136,9 +133,9 @@
      *
      * @return the FEB Hybrid ID
      */
-    @Field(names = { "feb_hybrid_id" })
-    public final int getFebHybridID() {
-        return getFieldValue("feb_hybrid_id");
+    @Field(names = {"feb_hybrid_id"})
+    public final Integer getFebHybridID() {
+        return this.getFieldValue("feb_hybrid_id");
     }
 
     /**
@@ -146,9 +143,9 @@
      *
      * @return the FEB ID
      */
-    @Field(names = { "feb_id" })
-    public final int getFebID() {
-        return getFieldValue("feb_id");
+    @Field(names = {"feb_id"})
+    public final Integer getFebID() {
+        return this.getFieldValue("feb_id");
     }
 
     /**
@@ -158,9 +155,9 @@
      * @see POSITRON
      * @return sensor side (ELECTRON or POSITRON)
      */
-    @Field(names = { "side" })
+    @Field(names = {"side"})
     public final String getSide() {
-        return getFieldValue("side");
+        return this.getFieldValue("side");
     }
 
     /**

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtDetectorSetup.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtDetectorSetup.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtDetectorSetup.java	Wed Jul  8 14:47:40 2015
@@ -21,15 +21,19 @@
 import org.lcsim.util.log.LogUtil;
 
 /**
- * This class puts {@link SvtConditions} data onto <code>HpsSiSensor</code>
- * objects.
+ * This class puts {@link SvtConditions} data onto <code>HpsSiSensor</code> objects.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Jeremy McCormick, SLAC
+ * @author Omar Moreno, UCSC
  */
 public final class SvtDetectorSetup implements ConditionsListener {
 
     /**
+     * Initialize logger.
+     */
+    private static Logger logger = LogUtil.create(SvtDetectorSetup.class);
+
+    /**
      * The number of noise samples.
      */
     private static final int NOISE_COUNT = 6;
@@ -40,19 +44,14 @@
     private static final int PEDESTAL_COUNT = 6;
 
     /**
-     * Initialize logger.
-     */
-    private static Logger logger = LogUtil.create(SvtDetectorSetup.class);
+     * Flag to enable/disable this class from within conditions manager.
+     */
+    private boolean enabled = true;
 
     /**
      * The name of the SVT subdetector in the detector model.
      */
     private String svtName = "Tracker";
-
-    /**
-     * Flag to enable/disable this class from within conditions manager.
-     */
-    private boolean enabled = true;
 
     /**
      * Constructor that takes name of SVT.
@@ -64,57 +63,28 @@
     }
 
     /**
-     * Set the name of the SVT in the detector model.
-     *
-     * @param svtName the name of the SVt in the detector model.
-     */
-    public void setSvtName(final String svtName) {
-        this.svtName = svtName;
-    }
-
-    /**
-     * Set whether this class is enabled to be activated on conditions changes.
-     *
-     * @param enabled <code>true</code> to enable
-     */
-    public void setEnabled(final boolean enabled) {
-        this.enabled = enabled;
-    }
-
-    /**
-     * Set the log level.
-     *
-     * @param level the log level
-     */
-    public void setLogLevel(final Level level) {
-        logger.setLevel(level);
-        logger.getHandlers()[0].setLevel(level);
-    }
-
-    /**
-     * Hook that activates this class when conditions change (new detector or
-     * run number).
+     * Hook that activates this class when conditions change (new detector or run number).
      *
      * @param event the conditions event
      */
     @Override
     public void conditionsChanged(final ConditionsEvent event) {
-        if (enabled) {
+        if (this.enabled) {
             final DatabaseConditionsManager manager = (DatabaseConditionsManager) event.getConditionsManager();
-            final Subdetector subdetector = manager.getDetectorObject().getSubdetector(svtName);
+            final Subdetector subdetector = manager.getDetectorObject().getSubdetector(this.svtName);
             if (subdetector != null) {
                 if (manager.isTestRun()) {
-                    final TestRunSvtConditions svtConditions = manager.getCachedConditions(
-                            TestRunSvtConditions.class, "test_run_svt_conditions").getCachedData();
-                    loadTestRun(subdetector, svtConditions);
+                    final TestRunSvtConditions svtConditions = manager.getCachedConditions(TestRunSvtConditions.class,
+                            "test_run_svt_conditions").getCachedData();
+                    this.loadTestRun(subdetector, svtConditions);
                 } else {
-                    final SvtConditions svtConditions = manager.getCachedConditions(
-                            SvtConditions.class, "svt_conditions").getCachedData();
-                    loadDefault(subdetector, svtConditions);
+                    final SvtConditions svtConditions = manager.getCachedConditions(SvtConditions.class,
+                            "svt_conditions").getCachedData();
+                    this.loadDefault(subdetector, svtConditions);
                 }
             } else {
                 logger.warning("no SVT detector was found so SvtDetectorSetup was NOT activated");
-                enabled = false;
+                this.enabled = false;
             }
         } else {
             logger.config("disabled");
@@ -140,7 +110,7 @@
         final SvtT0ShiftCollection t0Shifts = conditions.getT0Shifts();
 
         // Loop over sensors.
-        for (HpsSiSensor sensor : sensors) {
+        for (final HpsSiSensor sensor : sensors) {
 
             // Reset possible existing conditions data on sensor.
             sensor.reset();
@@ -159,9 +129,9 @@
 
             // Set the orientation of the sensor
             final String orientation = daqMap.getOrientation(daqPair);
-            if (orientation != null && orientation.contentEquals(SvtDaqMapping.AXIAL)) {
+            if (orientation != null && orientation.contentEquals(AbstractSvtDaqMapping.AXIAL)) {
                 sensor.setAxial(true);
-            } else if (orientation != null && orientation.contains(SvtDaqMapping.STEREO)) {
+            } else if (orientation != null && orientation.contains(AbstractSvtDaqMapping.STEREO)) {
                 sensor.setStereo(true);
             }
 
@@ -169,7 +139,7 @@
             final Collection<SvtChannel> channels = channelMap.find(daqPair);
 
             // Loop over the channels of the sensor.
-            for (SvtChannel channel : channels) {
+            for (final SvtChannel channel : channels) {
 
                 // Get conditions data for this channel.
                 final ChannelConstants constants = conditions.getChannelConstants(channel);
@@ -205,7 +175,8 @@
             // Set the t0 shift for the sensor.
             final SvtT0Shift sensorT0Shift = t0Shifts.getT0Shift(daqPair);
             if (sensorT0Shift == null) {
-                throw new RuntimeException("Failed to find T0 shift for sensor: " + sensor.getName() + ", FEB hybrid ID " + daqPair.getFirstElement() + ", FEB ID " + daqPair.getSecondElement());
+                throw new RuntimeException("Failed to find T0 shift for sensor: " + sensor.getName()
+                        + ", FEB hybrid ID " + daqPair.getFirstElement() + ", FEB ID " + daqPair.getSecondElement());
             }
             sensor.setT0Shift(sensorT0Shift.getT0Shift());
         }
@@ -230,7 +201,7 @@
         final TestRunSvtT0ShiftCollection t0Shifts = conditions.getT0Shifts();
 
         // Loop over sensors.
-        for (HpsSiSensor sensor : sensors) {
+        for (final HpsSiSensor sensor : sensors) {
 
             // Reset possible existing conditions data on sensor.
             sensor.reset();
@@ -249,9 +220,9 @@
 
             // Set the orientation of the sensor
             final String orientation = daqMap.getOrientation(daqPair);
-            if (orientation != null && orientation.contentEquals(TestRunSvtDaqMapping.AXIAL)) {
+            if (orientation != null && orientation.contentEquals(AbstractSvtDaqMapping.AXIAL)) {
                 sensor.setAxial(true);
-            } else if (orientation != null && orientation.contains(TestRunSvtDaqMapping.STEREO)) {
+            } else if (orientation != null && orientation.contains(AbstractSvtDaqMapping.STEREO)) {
                 sensor.setStereo(true);
             }
 
@@ -259,7 +230,7 @@
             final Collection<TestRunSvtChannel> channels = channelMap.find(daqPair);
 
             // Loop over the channels of the sensor.
-            for (TestRunSvtChannel channel : channels) {
+            for (final TestRunSvtChannel channel : channels) {
 
                 // Get conditions data for this channel.
                 final ChannelConstants constants = conditions.getChannelConstants(channel);
@@ -277,7 +248,7 @@
                 // channel
                 final double[] pedestal = new double[6];
                 final double[] noise = new double[6];
-                for (int sampleN = 0; sampleN < HpsTestRunSiSensor.NUMBER_OF_SAMPLES; sampleN++) {
+                for (int sampleN = 0; sampleN < HpsSiSensor.NUMBER_OF_SAMPLES; sampleN++) {
                     pedestal[sampleN] = constants.getCalibration().getPedestal(sampleN);
                     noise[sampleN] = constants.getCalibration().getNoise(sampleN);
                 }
@@ -297,4 +268,32 @@
             sensor.setT0Shift(sensorT0Shift.getT0Shift());
         }
     }
+
+    /**
+     * Set whether this class is enabled to be activated on conditions changes.
+     *
+     * @param enabled <code>true</code> to enable
+     */
+    public void setEnabled(final boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    /**
+     * Set the log level.
+     *
+     * @param level the log level
+     */
+    public void setLogLevel(final Level level) {
+        logger.setLevel(level);
+        logger.getHandlers()[0].setLevel(level);
+    }
+
+    /**
+     * Set the name of the SVT in the detector model.
+     *
+     * @param svtName the name of the SVt in the detector model.
+     */
+    public void setSvtName(final String svtName) {
+        this.svtName = svtName;
+    }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtGain.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtGain.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtGain.java	Wed Jul  8 14:47:40 2015
@@ -2,18 +2,15 @@
 
 import org.hps.conditions.api.BaseConditionsObject;
 import org.hps.conditions.api.BaseConditionsObjectCollection;
-import org.hps.conditions.database.Converter;
 import org.hps.conditions.database.Field;
-import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
 
 /**
  * This class represents the signal gain measurement for a single SVT channel.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
-@Table(names = { "svt_gains", "test_run_svt_gains" })
-@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED)
+@Table(names = {"svt_gains", "test_run_svt_gains"})
 public final class SvtGain extends BaseConditionsObject {
 
     /**
@@ -28,9 +25,9 @@
      *
      * @return The channel ID.
      */
-    @Field(names = { "svt_channel_id" })
-    public int getChannelID() {
-        return getFieldValue(Integer.class, "svt_channel_id");
+    @Field(names = {"svt_channel_id"})
+    public Integer getChannelID() {
+        return this.getFieldValue(Integer.class, "svt_channel_id");
     }
 
     /**
@@ -38,9 +35,9 @@
      *
      * @return The gain value.
      */
-    @Field(names = { "gain" })
-    public double getGain() {
-        return getFieldValue(Double.class, "gain");
+    @Field(names = {"gain"})
+    public Double getGain() {
+        return this.getFieldValue(Double.class, "gain");
     }
 
     /**
@@ -48,8 +45,8 @@
      *
      * @return The offset value.
      */
-    @Field(names = { "offset" })
-    public double getOffset() {
-        return getFieldValue(Double.class, "offset");
+    @Field(names = {"offset"})
+    public Double getOffset() {
+        return this.getFieldValue(Double.class, "offset");
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtShapeFitParameters.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtShapeFitParameters.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtShapeFitParameters.java	Wed Jul  8 14:47:40 2015
@@ -2,20 +2,16 @@
 
 import org.hps.conditions.api.BaseConditionsObject;
 import org.hps.conditions.api.BaseConditionsObjectCollection;
-import org.hps.conditions.database.Converter;
 import org.hps.conditions.database.Field;
-import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
 
 /**
  * This class encapsulates the shape fit parameters for an SVT channel.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Jeremy McCormick, SLAC
+ * @author Omar Moreno, UCSC
  */
 @Table(names = {"svt_shape_fit_parameters", "test_run_svt_shape_fit_parameters"})
-@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED)
-// TODO: This class needs better documentation as to what these parameters actually mean.
 public final class SvtShapeFitParameters extends BaseConditionsObject {
 
     /**
@@ -36,8 +32,8 @@
      * @return The amplitude.
      */
     @Field(names = {"amplitude"})
-    public double getAmplitude() {
-        return getFieldValue(Double.class, "amplitude");
+    public Double getAmplitude() {
+        return this.getFieldValue(Double.class, "amplitude");
     }
 
     /**
@@ -46,8 +42,8 @@
      * @return The SVT channel ID.
      */
     @Field(names = {"svt_channel_id"})
-    public int getChannelID() {
-        return getFieldValue(Integer.class, "svt_channel_id");
+    public Integer getChannelID() {
+        return this.getFieldValue(Integer.class, "svt_channel_id");
     }
 
     /**
@@ -56,8 +52,8 @@
      * @return t0
      */
     @Field(names = {"t0"})
-    public double getT0() {
-        return getFieldValue(Double.class, "t0");
+    public Double getT0() {
+        return this.getFieldValue(Double.class, "t0");
     }
 
     /**
@@ -66,8 +62,8 @@
      * @return the shaping time parameter
      */
     @Field(names = {"tp"})
-    public double getTp() {
-        return getFieldValue(Double.class, "tp");
+    public Double getTp() {
+        return this.getFieldValue(Double.class, "tp");
     }
 
     /**
@@ -76,8 +72,8 @@
      * @return the second shaping time parameter
      */
     @Field(names = {"tp2"})
-    public double getTp2() {
-        return getFieldValue(Double.class, "tp2");
+    public Double getTp2() {
+        return this.getFieldValue(Double.class, "tp2");
     }
 
     /**
@@ -87,10 +83,10 @@
      */
     public double[] toArray() {
         final double[] values = new double[ARRAY_SIZE];
-        values[0] = getAmplitude();
-        values[1] = getT0();
-        values[2] = getTp();
-        values[3] = getTp2();
+        values[0] = this.getAmplitude();
+        values[1] = this.getT0();
+        values[2] = this.getTp();
+        values[3] = this.getTp2();
         return values;
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtT0Shift.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtT0Shift.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtT0Shift.java	Wed Jul  8 14:47:40 2015
@@ -1,20 +1,17 @@
 package org.hps.conditions.svt;
 
-import org.hps.conditions.database.Converter;
 import org.hps.conditions.database.Field;
-import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
 import org.hps.util.Pair;
 
 /**
- * This class is a data holder for associating a t0 time shift with a specific sensor by DAQ pair
- * (FEB ID and FEB hybrid ID).
+ * This class is a data holder for associating a t0 time shift with a specific sensor by DAQ pair (FEB ID and FEB hybrid
+ * ID).
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Jeremy McCormick, SLAC
+ * @author Omar Moreno, UCSC
  */
-@Table(names = { "svt_t0_shifts" })
-@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED)
+@Table(names = {"svt_t0_shifts"})
 public final class SvtT0Shift extends AbstractSvtT0Shift {
 
     /**
@@ -33,7 +30,7 @@
         public SvtT0Shift getT0Shift(final Pair<Integer, Integer> pair) {
             final int febID = pair.getFirstElement();
             final int febHybridID = pair.getSecondElement();
-            for (SvtT0Shift t0Shift : this) {
+            for (final SvtT0Shift t0Shift : this) {
                 if (t0Shift.getFebID() == febID && t0Shift.getFebHybridID() == febHybridID) {
                     return t0Shift;
                 }
@@ -43,22 +40,22 @@
     }
 
     /**
+     * Get the FEB hybrid ID.
+     *
+     * @return the FEB hybrid ID
+     */
+    @Field(names = {"feb_hybrid_id"})
+    public Integer getFebHybridID() {
+        return this.getFieldValue("feb_hybrid_id");
+    }
+
+    /**
      * Get the FEB ID.
      *
      * @return the FEB ID
      */
-    @Field(names = { "feb_id" })
-    public int getFebID() {
-        return getFieldValue("feb_id");
-    }
-
-    /**
-     * Get the FEB hybrid ID.
-     *
-     * @return the FEB hybrid ID
-     */
-    @Field(names = { "feb_hybrid_id" })
-    public int getFebHybridID() {
-        return getFieldValue("feb_hybrid_id");
+    @Field(names = {"feb_id"})
+    public Integer getFebID() {
+        return this.getFieldValue("feb_id");
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtTimingConstants.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtTimingConstants.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtTimingConstants.java	Wed Jul  8 14:47:40 2015
@@ -2,9 +2,7 @@
 
 import org.hps.conditions.api.BaseConditionsObject;
 import org.hps.conditions.api.BaseConditionsObjectCollection;
-import org.hps.conditions.database.Converter;
 import org.hps.conditions.database.Field;
-import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
 
 /**
@@ -12,10 +10,9 @@
  * <p>
  * There will generally be only one of these records per run.
  *
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
  */
 @Table(names = {"svt_timing_constants"})
-@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED)
 public final class SvtTimingConstants extends BaseConditionsObject {
 
     /**

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtTimingConstantsLoader.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtTimingConstantsLoader.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtTimingConstantsLoader.java	Wed Jul  8 14:47:40 2015
@@ -9,6 +9,7 @@
 import java.util.List;
 import java.util.Set;
 
+import org.hps.conditions.api.ConditionsObjectException;
 import org.hps.conditions.api.ConditionsRecord;
 import org.hps.conditions.database.DatabaseConditionsManager;
 import org.hps.conditions.run.RunRange;
@@ -18,10 +19,10 @@
 /**
  * Load SVT timing constant data from the run spreadsheet and insert into the conditions database.
  * <p>
- * Be very careful about running this, because it will create many new conditions records that may already be present in the database. In fact, don't
- * run this at all without talking to me first. :-)
+ * Be very careful about running this, because it will create many new conditions records that may already be present in
+ * the database. In fact, don't run this at all without talking to me first. :-)
  *
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
  */
 public final class SvtTimingConstantsLoader {
 
@@ -58,7 +59,11 @@
             timing.setFieldValue("offset_time", offsetTime);
 
             final SvtTimingConstantsCollection collection = new SvtTimingConstantsCollection();
-            collection.add(timing);
+            try {
+                collection.add(timing);
+            } catch (final ConditionsObjectException e) {
+                throw new RuntimeException(e);
+            }
             collections.add(collection);
         }
         return collections;
@@ -74,8 +79,8 @@
      * @param offsetTime the offset time
      * @return the matching collection or <code>null</code> if not found
      */
-    private static SvtTimingConstantsCollection findCollection(final List<SvtTimingConstantsCollection> timingConstantsList, final int offsetPhase,
-            final double offsetTime) {
+    private static SvtTimingConstantsCollection findCollection(
+            final List<SvtTimingConstantsCollection> timingConstantsList, final int offsetPhase, final double offsetTime) {
         for (final SvtTimingConstantsCollection collection : timingConstantsList) {
             if (collection.find(offsetPhase, offsetTime) != null) {
                 return collection;
@@ -102,8 +107,8 @@
         final List<Collection<String>> uniqueValues = RunRange.getUniqueValues(ranges);
 
         /*
-         * System.out.println("unique values ..."); for (Collection<String> collection : uniqueValues) { for (String value : collection) {
-         * System.out.print(value + " "); } System.out.println(); }
+         * System.out.println("unique values ..."); for (Collection<String> collection : uniqueValues) { for (String
+         * value : collection) { System.out.print(value + " "); } System.out.println(); }
          */
 
         // Create a new collection for each unique combination set of timing constants.
@@ -113,8 +118,7 @@
         for (final SvtTimingConstantsCollection collection : collections) {
             int collectionId = 0;
             try {
-                collectionId = MANAGER.addCollection("svt_timing_constants", "SVT timing constants added by " + System.getProperty("user.name"),
-                        "timing constants from run spreadsheet");
+                collectionId = MANAGER.getCollectionId(collection, "timing constants from run spreadsheet");
                 collection.setCollectionId(collectionId);
                 collection.insert();
             } catch (final Exception e) {
@@ -134,7 +138,8 @@
             // Find the matching timing constants collection to use.
             final SvtTimingConstantsCollection collection = findCollection(collections, offsetPhase, offsetTime);
             if (collection != null) {
-                System.out.println("offset_phase : " + collection.get(0).getOffsetPhase() + ", offset_time: " + collection.get(0).getOffsetTime());
+                System.out.println("offset_phase : " + collection.get(0).getOffsetPhase() + ", offset_time: "
+                        + collection.get(0).getOffsetTime());
             }
 
             // Create a new conditions record with the run range.

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtChannel.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtChannel.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtChannel.java	Wed Jul  8 14:47:40 2015
@@ -4,27 +4,24 @@
 import java.util.Collection;
 import java.util.List;
 
-import org.hps.conditions.database.Converter;
 import org.hps.conditions.database.Field;
-import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
 import org.hps.util.Pair;
 
 /**
  * The implementation of {@link AbstractSvtChannel} for Test Run conditions.
  *
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Omar Moreno, UCSC
  */
 @Table(names = {"test_run_svt_channels"})
-@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED)
 public final class TestRunSvtChannel extends AbstractSvtChannel {
 
     /**
      * Concrete collection implementation for {@link TestRunSvtChannel} objects.
      */
     @SuppressWarnings("serial")
-    public static class TestRunSvtChannelCollection
-        extends AbstractSvtChannel.AbstractSvtChannelCollection<TestRunSvtChannel> {
+    public static class TestRunSvtChannelCollection extends
+            AbstractSvtChannel.AbstractSvtChannelCollection<TestRunSvtChannel> {
 
         /**
          * Find a collection of channels by their DAQ pair assignment.
@@ -47,30 +44,12 @@
     }
 
     /**
-     * Get the FPGA ID.
+     * Implementation of equals.
      *
-     * @return the FPGA ID
-     */
-    @Field(names = {"fpga"})
-    public int getFpgaID() {
-        return getFieldValue("fpga");
-    }
-
-    /**
-     * Get the hybrid ID.
-     *
-     * @return the hybrid ID
-     */
-    @Field(names = {"hybrid"})
-    public int getHybridID() {
-        return getFieldValue("hybrid");
-    }
-
-    /**
-     * Implementation of equals.
      * @param o the other object
      * @return <code>true</code> if the object equals this one; false if not.
      */
+    @Override
     public boolean equals(final Object o) {
         if (o == null) {
             return false;
@@ -82,7 +61,27 @@
             return true;
         }
         final TestRunSvtChannel channel = (TestRunSvtChannel) o;
-        return getChannelID() == channel.getChannelID() && getFpgaID() == channel.getFpgaID()
-                && getHybridID() == channel.getHybridID() && getChannel() == channel.getChannel();
+        return this.getChannelID() == channel.getChannelID() && this.getFpgaID() == channel.getFpgaID()
+                && this.getHybridID() == channel.getHybridID() && this.getChannel() == channel.getChannel();
+    }
+
+    /**
+     * Get the FPGA ID.
+     *
+     * @return the FPGA ID
+     */
+    @Field(names = {"fpga"})
+    public Integer getFpgaID() {
+        return this.getFieldValue("fpga");
+    }
+
+    /**
+     * Get the hybrid ID.
+     *
+     * @return the hybrid ID
+     */
+    @Field(names = {"hybrid"})
+    public Integer getHybridID() {
+        return this.getFieldValue("hybrid");
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtConditions.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtConditions.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtConditions.java	Wed Jul  8 14:47:40 2015
@@ -1,21 +1,20 @@
 package org.hps.conditions.svt;
+
+import static org.hps.conditions.svt.AbstractSvtChannel.MAX_NUMBER_OF_SAMPLES;
 
 import org.hps.conditions.svt.TestRunSvtChannel.TestRunSvtChannelCollection;
 import org.hps.conditions.svt.TestRunSvtDaqMapping.TestRunSvtDaqMappingCollection;
-
 import org.hps.conditions.svt.TestRunSvtT0Shift.TestRunSvtT0ShiftCollection;
 
 // TODO: Move all constants to their own class
-import static org.hps.conditions.svt.SvtChannel.MAX_NUMBER_OF_SAMPLES;
 
 /**
- * This class contains all test run SVT conditions data by readout channel.
- * {@link TestRunSvtChannel} objects from the SVT channel map should be used to
- * lookup the conditions using the
- * {@link #getChannelConstants(TestRunSvtChannel)} method.
+ * This class contains all test run SVT conditions data by readout channel. {@link TestRunSvtChannel} objects from the
+ * SVT channel map should be used to lookup the conditions using the {@link #getChannelConstants(TestRunSvtChannel)}
+ * method.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Jeremy McCormick, SLAC
+ * @author Omar Moreno, UCSC
  */
 public final class TestRunSvtConditions extends AbstractSvtConditions {
 
@@ -25,48 +24,46 @@
     private static final int DIVIDER_LEN = 115;
 
     /**
-     * Get the {@link TestRunSvtDaqMappingCollection} associated with these
-     * conditions.
-     *
-     * @return The SVT DAQ map.
-     */
-    @Override
-    public TestRunSvtDaqMappingCollection getDaqMap() {
-        return (TestRunSvtDaqMappingCollection) daqMap;
-    }
-
-    /**
      * Get the {@link TestRunSvtChannelCollection} for this set of conditions.
      *
      * @return The SVT channel map.
      */
     @Override
     public TestRunSvtChannelCollection getChannelMap() {
-        return (TestRunSvtChannelCollection) channelMap;
+        return (TestRunSvtChannelCollection) this.channelMap;
     }
 
     /**
-     * Get the {@link TestRunSvtT0ShiftCollection} associated with these
-     * conditions.
+     * Get the {@link TestRunSvtDaqMappingCollection} associated with these conditions.
+     *
+     * @return The SVT DAQ map.
+     */
+    @Override
+    public TestRunSvtDaqMappingCollection getDaqMap() {
+        return (TestRunSvtDaqMappingCollection) this.daqMap;
+    }
+
+    /**
+     * Get the {@link TestRunSvtT0ShiftCollection} associated with these conditions.
      *
      * @return The {@link TestRunSvtT0ShiftCollection}
      */
     @Override
     public TestRunSvtT0ShiftCollection getT0Shifts() {
-        return (TestRunSvtT0ShiftCollection) t0Shifts;
+        return (TestRunSvtT0ShiftCollection) this.t0Shifts;
     }
 
     /**
-     * Convert this object to a human readable string. This method prints a
-     * formatted table of channel data independently of how its member objects
-     * implement their string conversion method. For now, it does not print the
+     * Convert this object to a human readable string. This method prints a formatted table of channel data
+     * independently of how its member objects implement their string conversion method. For now, it does not print the
      * time shifts by sensor as all other information is by channel.
      *
      * @return this object converted to a string, without the DAQ map
      */
     // TODO: Make this look more human readable. At the moment, reading this requires a huge terminal window.
+    @Override
     public String toString() {
-        StringBuffer buff = new StringBuffer();
+        final StringBuffer buff = new StringBuffer();
 
         buff.append('\n');
         buff.append("Printing SVTConditions ...");
@@ -123,18 +120,19 @@
         }
         buff.append('\n');
         // Loop over channels.
-        for (TestRunSvtChannel channel : this.getChannelMap()) {
+        for (final TestRunSvtChannel channel : this.getChannelMap()) {
 
             System.out.println("Channel: " + channel.toString());
 
             // Get the conditions for the channel.
-            final ChannelConstants constants = getChannelConstants(channel);
+            final ChannelConstants constants = this.getChannelConstants(channel);
             final SvtGain gain = constants.getGain();
             final SvtShapeFitParameters shapeFit = constants.getShapeFitParameters();
             final SvtCalibration calibration = constants.getCalibration();
 
             // Channel data.
-            buff.append(String.format("%-6d %-5d %-8d %-8d ", channel.getChannelID(), channel.getFpgaID(), channel.getHybridID(), channel.getChannel()));
+            buff.append(String.format("%-6d %-5d %-8d %-8d ", channel.getChannelID(), channel.getFpgaID(),
+                    channel.getHybridID(), channel.getChannel()));
 
             // Calibration.
             for (int sample = 0; sample < MAX_NUMBER_OF_SAMPLES; sample++) {
@@ -150,8 +148,8 @@
             buff.append(String.format("%-6.4f %-9.4f ", gain.getGain(), gain.getOffset()));
 
             // Pulse shape.
-            buff.append(String.format("%-10.4f %-8.4f %-8.4f", 
-                    shapeFit.getAmplitude(), shapeFit.getT0(), shapeFit.getTp()));
+            buff.append(String.format("%-10.4f %-8.4f %-8.4f", shapeFit.getAmplitude(), shapeFit.getT0(),
+                    shapeFit.getTp()));
 
             // Bad channel.
             buff.append(constants.isBadChannel());
@@ -163,7 +161,7 @@
         buff.append("Printing SVT DAQ Map...");
         buff.append('\n');
         buff.append('\n');
-        buff.append(getDaqMap());
+        buff.append(this.getDaqMap());
 
         return buff.toString();
     }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtConditionsConverter.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtConditionsConverter.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtConditionsConverter.java	Wed Jul  8 14:47:40 2015
@@ -14,7 +14,7 @@
 /**
  * Converter for combined Test Run SVT conditions {@link TestRunSvtConditions} object.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public final class TestRunSvtConditionsConverter extends AbstractSvtConditionsConverter<TestRunSvtConditions> {
 
@@ -23,49 +23,6 @@
      */
     public TestRunSvtConditionsConverter() {
         this.conditions = new TestRunSvtConditions();
-    }
-
-    /**
-     * Get the Test Run {@link SvtShapeFitParametersCollection}.
-     *
-     * @param manager the conditions manager
-     * @return the Test Run {@link SvtShapeFitParametersCollection}
-     */
-    protected SvtShapeFitParametersCollection getSvtShapeFitParametersCollection(
-            final DatabaseConditionsManager manager) {
-        return manager.getCachedConditions(SvtShapeFitParametersCollection.class,
-                "test_run_svt_shape_fit_parameters").getCachedData();
-    }
-
-    /**
-     * Get the Test Run series of {@link SvtBadChannelCollection} objects
-     *
-     * @param manager the conditions manager
-     * @return the Test Run bad channel collections
-     */
-    protected ConditionsSeries<SvtBadChannel, SvtBadChannelCollection> getSvtBadChannelSeries(
-            final DatabaseConditionsManager manager) {
-        return manager.getConditionsSeries(SvtBadChannelCollection.class, "test_run_svt_bad_channels");
-    }
-
-    /**
-     * Get the Test Run {@link SvtCalibrationCollection}.
-     *
-     * @param manager the conditions manager
-     * @return the Test Run {@link SvtCalibrationCollection}
-     */
-    protected SvtCalibrationCollection getSvtCalibrationCollection(final DatabaseConditionsManager manager) {
-        return manager.getCachedConditions(SvtCalibrationCollection.class, "test_run_svt_calibrations").getCachedData();
-    }
-
-    /**
-     * Get the Test Run {@link SvtGainCollection}.
-     *
-     * @param manager the conditions manager
-     * @return the Test Run {@link SvtGainCollection}
-     */
-    protected SvtGainCollection getSvtGainCollection(final DatabaseConditionsManager manager) {
-        return manager.getCachedConditions(SvtGainCollection.class, "test_run_svt_gains").getCachedData();
     }
 
     /**
@@ -85,25 +42,72 @@
 
         // Create the SVT conditions object to use to encapsulate SVT condition
         // collections
-        conditions.setChannelMap(channels);
+        this.conditions.setChannelMap(channels);
 
         // Get the DAQ map from the conditions database
         final TestRunSvtDaqMappingCollection daqMap = dbConditionsManager.getCachedConditions(
                 TestRunSvtDaqMappingCollection.class, "test_run_svt_daq_map").getCachedData();
-        conditions.setDaqMap(daqMap);
+        this.conditions.setDaqMap(daqMap);
 
         // Get the collection of T0 shifts from the conditions database
         final TestRunSvtT0ShiftCollection t0Shifts = dbConditionsManager.getCachedConditions(
                 TestRunSvtT0ShiftCollection.class, "test_run_svt_t0_shifts").getCachedData();
-        conditions.setT0Shifts(t0Shifts);
+        this.conditions.setT0Shifts(t0Shifts);
 
-        conditions = super.getData(manager, name);
+        this.conditions = super.getData(manager, name);
 
-        return conditions;
+        return this.conditions;
+    }
+
+    /**
+     * Get the Test Run series of {@link SvtBadChannelCollection} objects
+     *
+     * @param manager the conditions manager
+     * @return the Test Run bad channel collections
+     */
+    @Override
+    protected ConditionsSeries<SvtBadChannel, SvtBadChannelCollection> getSvtBadChannelSeries(
+            final DatabaseConditionsManager manager) {
+        return manager.getConditionsSeries(SvtBadChannelCollection.class, "test_run_svt_bad_channels");
+    }
+
+    /**
+     * Get the Test Run {@link SvtCalibrationCollection}.
+     *
+     * @param manager the conditions manager
+     * @return the Test Run {@link SvtCalibrationCollection}
+     */
+    @Override
+    protected SvtCalibrationCollection getSvtCalibrationCollection(final DatabaseConditionsManager manager) {
+        return manager.getCachedConditions(SvtCalibrationCollection.class, "test_run_svt_calibrations").getCachedData();
+    }
+
+    /**
+     * Get the Test Run {@link SvtGainCollection}.
+     *
+     * @param manager the conditions manager
+     * @return the Test Run {@link SvtGainCollection}
+     */
+    @Override
+    protected SvtGainCollection getSvtGainCollection(final DatabaseConditionsManager manager) {
+        return manager.getCachedConditions(SvtGainCollection.class, "test_run_svt_gains").getCachedData();
+    }
+
+    /**
+     * Get the Test Run {@link SvtShapeFitParametersCollection}.
+     *
+     * @param manager the conditions manager
+     * @return the Test Run {@link SvtShapeFitParametersCollection}
+     */
+    @Override
+    protected SvtShapeFitParametersCollection getSvtShapeFitParametersCollection(final DatabaseConditionsManager manager) {
+        return manager.getCachedConditions(SvtShapeFitParametersCollection.class, "test_run_svt_shape_fit_parameters")
+                .getCachedData();
     }
 
     /**
      * Get the type handled by this converter.
+     *
      * @return The type handled by this converter.
      */
     @Override

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtDaqMapping.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtDaqMapping.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtDaqMapping.java	Wed Jul  8 14:47:40 2015
@@ -1,19 +1,17 @@
 package org.hps.conditions.svt;
 
-import org.hps.conditions.database.Converter;
 import org.hps.conditions.database.Field;
-import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
 import org.hps.util.Pair;
 import org.lcsim.detector.tracker.silicon.HpsSiSensor;
+import org.lcsim.detector.tracker.silicon.HpsTestRunSiSensor;
 
 /**
  * This class encapsulates the Test Run SVT DAQ map.
  *
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Omar Moreno, UCSC
  */
-@Table(names = { "test_run_svt_daq_map" })
-@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED)
+@Table(names = {"test_run_svt_daq_map"})
 public final class TestRunSvtDaqMapping extends AbstractSvtDaqMapping {
 
     /**
@@ -31,7 +29,7 @@
         public Pair<Integer, Integer> getDaqPair(final HpsSiSensor sensor) {
 
             final String svtHalf = sensor.isTopLayer() ? TOP_HALF : BOTTOM_HALF;
-            for (TestRunSvtDaqMapping daqMapping : this) {
+            for (final TestRunSvtDaqMapping daqMapping : this) {
 
                 if (svtHalf.equals(daqMapping.getSvtHalf()) && daqMapping.getLayerNumber() == sensor.getLayerNumber()) {
 
@@ -44,15 +42,15 @@
         /**
          * Get the orientation of a sensor using the FPGA and Hybrid ID. If the FPGA and Hybrid ID combination is not
          * found, return null.
-         * 
+         *
          * @param daqPair (Pair<FPGA ID, Hybrid ID>) for a given sensor
          * @return "A" if sensor orientation is Axial; "S" if Stereo; null if daqPair doesn't exist
          */
         @Override
         public String getOrientation(final Pair<Integer, Integer> daqPair) {
             for (final TestRunSvtDaqMapping daqMapping : this) {
-                if (daqPair.getFirstElement() == ((TestRunSvtDaqMapping) daqMapping).getFpgaID()
-                        && daqPair.getSecondElement() == ((TestRunSvtDaqMapping) daqMapping).getHybridID()) {
+                if (daqPair.getFirstElement() == daqMapping.getFpgaID()
+                        && daqPair.getSecondElement() == daqMapping.getHybridID()) {
                     return daqMapping.getOrientation();
                 }
             }
@@ -61,9 +59,10 @@
 
         /**
          * Convert {@link TestRunSvtDaqMapping} to a string.
-         * 
+         *
          * @return This object converted to a string.
          */
+        @Override
         public String toString() {
             final StringBuffer buffer = new StringBuffer();
             buffer.append("FPGA ID: ");
@@ -79,8 +78,8 @@
             buffer.append('\n');
             buffer.append("----------------------");
             buffer.append('\n');
-            for (TestRunSvtDaqMapping daqMapping : this) {
-                final TestRunSvtDaqMapping testRunDaqMapping = (TestRunSvtDaqMapping) daqMapping;
+            for (final TestRunSvtDaqMapping daqMapping : this) {
+                final TestRunSvtDaqMapping testRunDaqMapping = daqMapping;
                 buffer.append(testRunDaqMapping.getFpgaID());
                 buffer.append("    ");
                 buffer.append(testRunDaqMapping.getHybridID());
@@ -102,9 +101,9 @@
      *
      * @return the FPGA ID
      */
-    @Field(names = { "fpga" })
-    public int getFpgaID() {
-        return getFieldValue("fpga");
+    @Field(names = {"fpga"})
+    public Integer getFpgaID() {
+        return this.getFieldValue("fpga");
     }
 
     /**
@@ -112,8 +111,8 @@
      *
      * @return the Hybrid ID
      */
-    @Field(names = { "hybrid" })
-    public int getHybridID() {
-        return getFieldValue("hybrid");
+    @Field(names = {"hybrid"})
+    public Integer getHybridID() {
+        return this.getFieldValue("hybrid");
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtT0Shift.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtT0Shift.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtT0Shift.java	Wed Jul  8 14:47:40 2015
@@ -1,27 +1,23 @@
 package org.hps.conditions.svt;
 
-import org.hps.conditions.database.Converter;
 import org.hps.conditions.database.Field;
-import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
 import org.hps.util.Pair;
 
 /**
- * This class is a container that allows associating a t0 shift with a specific
- * sensor by FPGA ID and hybrid ID.
+ * This class is a container that allows associating a t0 shift with a specific sensor by FPGA ID and hybrid ID.
  *
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Omar Moreno, UCSC
  */
 @Table(names = {"test_run_svt_t0_shifts"})
-@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED)
 public final class TestRunSvtT0Shift extends AbstractSvtT0Shift {
 
     /**
      * Collection implementation for {@link TestRunSvtT0Shift} objects.
      */
     @SuppressWarnings("serial")
-    public static class TestRunSvtT0ShiftCollection 
-        extends AbstractSvtT0Shift.AbstractSvtT0ShiftCollection<TestRunSvtT0Shift> {
+    public static class TestRunSvtT0ShiftCollection extends
+            AbstractSvtT0Shift.AbstractSvtT0ShiftCollection<TestRunSvtT0Shift> {
 
         /**
          * Get the {@link TestRunSvtT0Shift} associated with a given DAQ pair
@@ -48,8 +44,8 @@
      * @return the FPGA ID
      */
     @Field(names = {"fpga"})
-    public int getFpgaID() {
-        return getFieldValue("fpga");
+    public Integer getFpgaID() {
+        return this.getFieldValue("fpga");
     }
 
     /**
@@ -58,7 +54,7 @@
      * @return the hybrid ID
      */
     @Field(names = {"hybrid"})
-    public int getHybridID() {
-        return getFieldValue("hybrid");
+    public Integer getHybridID() {
+        return this.getFieldValue("hybrid");
     }
 }

Modified: java/trunk/conditions/src/main/java/org/hps/conditions/svt/package-info.java
 =============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/package-info.java	(original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/package-info.java	Wed Jul  8 14:47:40 2015
@@ -1,6 +1,8 @@
 /**
  * Implementation of detector conditions API for the HPS SVT.
  *
+ * @author Omar Moreno, UCSC
+ * @author Jeremy McCormick, SLAC
  * @see org.hps.conditions.api
  * @see org.hps.conditions.api.ConditionsObject
  * @see org.hps.conditions.api.ConditionsObjectCollection
@@ -10,7 +12,6 @@
  * @see SvtCalibration
  * @see SvtT0Shift
  * @see SvtBadChannel
- * @author <a href="[log in to unmask]">Omar Moreno</a>
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
  */
 package org.hps.conditions.svt;
+

Modified: java/trunk/conditions/src/test/java/org/hps/conditions/ConditionsDriverTest.java
 =============================================================================
--- java/trunk/conditions/src/test/java/org/hps/conditions/ConditionsDriverTest.java	(original)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/ConditionsDriverTest.java	Wed Jul  8 14:47:40 2015
@@ -15,9 +15,26 @@
 /**
  * This is a basic test of using ConditionsDriver that doesn't actually check anything at the moment.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public final class ConditionsDriverTest extends TestCase {
+
+    /**
+     * This {@link org.lcsim.util.Driver} prints out when the conditions change.
+     */
+    static class CheckDriver extends Driver {
+
+        /**
+         * Hook for conditions system change.
+         * 
+         * @param detector the detector object
+         */
+        @Override
+        public void detectorChanged(final Detector detector) {
+            System.out.println("detectorChanged - detector " + detector.getDetectorName() + " and run #"
+                    + DatabaseConditionsManager.getInstance().getRun());
+        }
+    }
 
     /**
      * The run number to use for the test.
@@ -26,6 +43,7 @@
 
     /**
      * Test the {@link ConditionsDriver} on Test Run data.
+     * 
      * @throws Exception if there is a test error or conditions error
      */
     public void testConditionsDriverTestRun() throws Exception {
@@ -48,19 +66,4 @@
         loop.add(new CheckDriver());
         loop.loop(-1);
     }
-
-    /**
-     * This {@link org.lcsim.util.Driver} prints out when the conditions change.
-     */
-    static class CheckDriver extends Driver {
-
-        /**
-         * Hook for conditions system change.
-         * @param detector the detector object
-         */
-        public void detectorChanged(final Detector detector) {
-            System.out.println("detectorChanged - detector " + detector.getDetectorName()
-                    + " and run #" + DatabaseConditionsManager.getInstance().getRun());
-        }
-    }
 }

Modified: java/trunk/conditions/src/test/java/org/hps/conditions/EngRunConditionsTest.java
 =============================================================================
--- java/trunk/conditions/src/test/java/org/hps/conditions/EngRunConditionsTest.java	(original)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/EngRunConditionsTest.java	Wed Jul  8 14:47:40 2015
@@ -29,86 +29,36 @@
 /**
  * This tests the basic correctness of conditions for an LCIO file generated from Engineering Run data.
  * <p>
- * Currently only ECAL conditions are handled here but SVT should be added once that information is in the
- * production database and there are runs available with Tracker data.
+ * Currently only ECAL conditions are handled here but SVT should be added once that information is in the production
+ * database and there are runs available with Tracker data.
  * <p>
  * This test will need to be updated if the default conditions sets are changed for the Eng Run.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public final class EngRunConditionsTest extends TestCase {
 
     /**
-     * Number of events to process.
-     */
-    private static final int EVENT_COUNT = 100;
-
-    /**
-     * Data file URL.
-     */
-    private static final String URL = "http://www.lcsim.org/test/hps-java/hps_003393.0_recon_20141225-0-100.slcio";
-
-    /**
-     * The run number to use for the test.
-     */
-    private static final int RUN_NUMBER = 3393;
-
-    /**
-     * Number of ECAL channels.
-     */
-    private static final int CHANNEL_COUNT = 442;
-
-    /**
-     * Run start.
-     */
-    private static final int RUN_START = 2000;
-
-    /**
-     * Run end.
-     */
-    private static final int RUN_END = 9999;
-
-    /**
-     * Test Eng Run conditions.
-     * @throws Exception if there is an error (record processing problem)
-     */
-    public void test() throws Exception {
-
-        final DatabaseConditionsManager manager = DatabaseConditionsManager.getInstance();
-        DatabaseConditionsManager.getLogger().setLevel(Level.ALL);
-        manager.setTag("pass0");
-        manager.setXmlConfig("/org/hps/conditions/config/conditions_database_engrun.xml");
-
-        final FileCache cache = new FileCache();
-        final File inputFile = cache.getCachedFile(new URL(URL));
-
-        final LCSimLoop loop = new LCSimLoop();
-        loop.add(new EventMarkerDriver());
-        loop.add(new ConditionsCheckDriver());
-        loop.setLCIORecordSource(inputFile);
-        loop.loop(EVENT_COUNT);
-    }
-
-    /**
-     * Check the run numbers of the conditions records.
-     * @param collection the conditions collection
-     */
-    static void checkRunNumbers(final BaseConditionsObjectCollection<?> collection) {
-        assertTrue("Run start out of range.", collection.getConditionsRecord().getRunStart() >= RUN_START);
-        assertTrue("Run end out of range.", collection.getConditionsRecord().getRunEnd() <= RUN_END);
-    }
-
-    /**
      * This {@link org.lcsim.util.Driver} performs basic conditions data checks.
      */
     static class ConditionsCheckDriver extends Driver {
 
         /**
+         * Collection ID of calibrations.
+         */
+        private static final Integer CALIBRATIONS_COLLECTION_ID = 4;
+
+        /**
          * Answer for gain value check of single channel.
          */
         private static final double GAIN_ANSWER = 0.17;
 
         /**
+         * Collection ID of gains.
+         */
+        private static final Integer GAINS_COLLECTION_ID = 4;
+
+        /**
          * Answer for noise value check of single channel.
          */
         private static final double NOISE_ANSWER = 2.74;
@@ -119,16 +69,6 @@
         private static final double PEDESTAL_ANSWER = 105.78;
 
         /**
-         * Collection ID of calibrations.
-         */
-        private static final Integer CALIBRATIONS_COLLECTION_ID = 4;
-
-        /**
-         * Collection ID of gains.
-         */
-        private static final Integer GAINS_COLLECTION_ID = 4;
-
-        /**
          * Flag if {@link #detectorChanged(Detector)} is activated.
          */
         private boolean detectorChangedCalled = false;
@@ -139,50 +79,52 @@
         private EcalConditions ecalConditions;
 
         /**
-         * Hook when conditions are updated.  Performs various checks for test.
+         * Hook when conditions are updated. Performs various checks for test.
+         *
          * @param detector the detector object
          */
+        @Override
         public void detectorChanged(final Detector detector) {
 
             assertEquals("Wrong run number.", RUN_NUMBER, DatabaseConditionsManager.getInstance().getRun());
 
             final DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
 
-            final EcalChannelCollection channels = conditionsManager.getCachedConditions(
-                    EcalChannelCollection.class, "ecal_channels").getCachedData();
+            final EcalChannelCollection channels = conditionsManager.getCachedConditions(EcalChannelCollection.class,
+                    "ecal_channels").getCachedData();
             assertEquals("Wrong number of channels.", CHANNEL_COUNT, channels.size());
-            assertEquals("Wrong channel collection ID.", new Integer(2), channels.getConditionsRecord().getCollectionId());
+            // assertEquals("Wrong channel collection ID.", 2, channels.getConditionsRecord().getCollectionId());
             checkRunNumbers(channels);
 
-            final EcalGainCollection gains = conditionsManager.getCachedConditions(
-                    EcalGainCollection.class, "ecal_gains").getCachedData();
+            final EcalGainCollection gains = conditionsManager.getCachedConditions(EcalGainCollection.class,
+                    "ecal_gains").getCachedData();
             assertEquals("Wrong number of gains.", CHANNEL_COUNT, gains.size());
-            assertEquals("Wrong gains collection ID.", GAINS_COLLECTION_ID,
-                    gains.getConditionsRecord().getCollectionId());
+            // assertEquals("Wrong gains collection ID.", GAINS_COLLECTION_ID,
+            // gains.getConditionsRecord().getCollectionId());
             checkRunNumbers(gains);
 
             final EcalCalibrationCollection calibrations = conditionsManager.getCachedConditions(
                     EcalCalibrationCollection.class, "ecal_calibrations").getCachedData();
             assertEquals("Wrong number of calibrations.", CHANNEL_COUNT, calibrations.size());
-            assertEquals("Wrong calibrations collection ID.", CALIBRATIONS_COLLECTION_ID,
-                    calibrations.getConditionsRecord().getCollectionId());
+            // assertEquals("Wrong calibrations collection ID.", CALIBRATIONS_COLLECTION_ID,
+            // calibrations.getConditionsRecord().getCollectionId());
             checkRunNumbers(calibrations);
 
-            //EcalLedCollection leds = conditionsManager.getCollection(EcalLedCollection.class);
-            //assertEquals("Wrong number of LEDs.", nChannels, leds.size());
-            //assertEquals("Wrong LEDs collection ID.", 2, leds.getConditionsRecord().getCollectionId());
-            //checkRunNumbers(leds);
-
-            //EcalTimeShiftCollection timeShifts = conditionsManager.getCollection(EcalTimeShiftCollection.class);
-            //assertEquals("Wrong number of timeShifts.", nChannels, timeShifts.size());
-            //assertEquals("Wrong LEDs collection ID.", 2, timeShifts.getConditionsRecord().getCollectionId());
-            //checkRunNumbers(timeShifts);
-
-            ecalConditions = conditionsManager.getCachedConditions(
-                    EcalConditions.class, "ecal_conditions").getCachedData();
+            // EcalLedCollection leds = conditionsManager.getCollection(EcalLedCollection.class);
+            // assertEquals("Wrong number of LEDs.", nChannels, leds.size());
+            // assertEquals("Wrong LEDs collection ID.", 2, leds.getConditionsRecord().getCollectionId());
+            // checkRunNumbers(leds);
+
+            // EcalTimeShiftCollection timeShifts = conditionsManager.getCollection(EcalTimeShiftCollection.class);
+            // assertEquals("Wrong number of timeShifts.", nChannels, timeShifts.size());
+            // assertEquals("Wrong LEDs collection ID.", 2, timeShifts.getConditionsRecord().getCollectionId());
+            // checkRunNumbers(timeShifts);
+
+            this.ecalConditions = conditionsManager.getCachedConditions(EcalConditions.class, "ecal_conditions")
+                    .getCachedData();
             final Set<EcalChannelConstants> channelConstants = new LinkedHashSet<EcalChannelConstants>();
-            for (EcalChannel channel : ecalConditions.getChannelCollection().sorted()) {
-                channelConstants.add(ecalConditions.getChannelConstants(channel));
+            for (final EcalChannel channel : this.ecalConditions.getChannelCollection().sorted()) {
+                channelConstants.add(this.ecalConditions.getChannelConstants(channel));
             }
             assertEquals("Wrong number of channel constants.", CHANNEL_COUNT, channelConstants.size());
 
@@ -191,13 +133,25 @@
             assertEquals("Wrong noise value.", NOISE_ANSWER, channelInfo.getCalibration().getNoise());
             assertEquals("Wrong gain value.", GAIN_ANSWER, channelInfo.getGain().getGain());
 
-            detectorChangedCalled = true;
+            this.detectorChangedCalled = true;
         }
 
         /**
-         * Event processing.  Performs a few conditions system and geometry checks.
+         * End of data hook. Checks that {@link #detectorChanged(Detector)} was called.
+         */
+        @Override
+        public void endOfData() {
+            if (!this.detectorChangedCalled) {
+                throw new RuntimeException("The detectorChanged method was never called.");
+            }
+        }
+
+        /**
+         * Event processing. Performs a few conditions system and geometry checks.
+         *
          * @param event the LCSim event
          */
+        @Override
         public void process(final EventHeader event) {
             assertEquals("Wrong run number.", RUN_NUMBER, event.getRunNumber());
             if (event.hasCollection(CalorimeterHit.class, "EcalCalHits")) {
@@ -213,12 +167,11 @@
                     if (hit.getIdentifier() == null) {
                         throw new RuntimeException("The hit ID is null.");
                     }
-                    assertEquals("The crystal and hit ID are different.",
-                            crystal.getIdentifier(), hit.getIdentifier());
-
-                    final EcalChannel channel = ecalConditions.getChannelCollection().findGeometric(
+                    assertEquals("The crystal and hit ID are different.", crystal.getIdentifier(), hit.getIdentifier());
+
+                    final EcalChannel channel = this.ecalConditions.getChannelCollection().findGeometric(
                             hit.getIdentifier().getValue());
-                    final EcalChannelConstants constants = ecalConditions.getChannelConstants(channel);
+                    final EcalChannelConstants constants = this.ecalConditions.getChannelConstants(channel);
 
                     assertTrue("The crystal gain is invalid.", constants.getGain().getGain() > 0.);
                     assertTrue("The crystal pedestal is invalid.", constants.getCalibration().getPedestal() > 0.);
@@ -226,14 +179,57 @@
                 }
             }
         }
-
-        /**
-         * End of data hook.  Checks that {@link #detectorChanged(Detector)} was called.
-         */
-        public void endOfData() {
-            if (!detectorChangedCalled) {
-                throw new RuntimeException("The detectorChanged method was never called.");
-            }
-        }
+    }
+
+    /**
+     * Number of ECAL channels.
+     */
+    private static final int CHANNEL_COUNT = 442;
+
+    /**
+     * Number of events to process.
+     */
+    private static final int EVENT_COUNT = 100;
+
+    /**
+     * The run number to use for the test.
+     */
+    private static final int RUN_NUMBER = 3393;
+
+    /**
+     * Data file URL.
+     */
+    private static final String URL = "http://www.lcsim.org/test/hps-java/hps_003393.0_recon_20141225-0-100.slcio";
+
+    /**
+     * Check the run numbers of the conditions records.
+     *
+     * @param collection the conditions collection
+     */
+    static void checkRunNumbers(final BaseConditionsObjectCollection<?> collection) {
+        // assertTrue("Run start out of range.", collection.getConditionsRecord().getRunStart() >= RUN_START);
+        // assertTrue("Run end out of range.", collection.getConditionsRecord().getRunEnd() <= RUN_END);
+    }
+
+    /**
+     * Test Eng Run conditions.
+     *
+     * @throws Exception if there is an error (record processing problem)
+     */
+    public void test() throws Exception {
+
+        final DatabaseConditionsManager manager = DatabaseConditionsManager.getInstance();
+        DatabaseConditionsManager.getLogger().setLevel(Level.ALL);
+        manager.setTag("pass0");
+        manager.setXmlConfig("/org/hps/conditions/config/conditions_database_engrun.xml");
+
+        final FileCache cache = new FileCache();
+        final File inputFile = cache.getCachedFile(new URL(URL));
+
+        final LCSimLoop loop = new LCSimLoop();
+        loop.add(new EventMarkerDriver());
+        loop.add(new ConditionsCheckDriver());
+        loop.setLCIORecordSource(inputFile);
+        loop.loop(EVENT_COUNT);
     }
 }

Modified: java/trunk/conditions/src/test/java/org/hps/conditions/RunNumberTest.java
 =============================================================================
--- java/trunk/conditions/src/test/java/org/hps/conditions/RunNumberTest.java	(original)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/RunNumberTest.java	Wed Jul  8 14:47:40 2015
@@ -20,9 +20,63 @@
 /**
  * This class checks that event processing works correctly for files that have multiple runs in them.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public final class RunNumberTest extends TestCase {
+
+    /**
+     * Simple Driver to store information about runs processed.
+     */
+    static class RunNumberDriver extends Driver {
+
+        /**
+         * Reference to conditions manager.
+         */
+        private static DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
+
+        /**
+         * Number of times {@link #detectorChanged(Detector)} was called.
+         */
+        private int nDetectorChanged = 0;
+
+        /**
+         * Number of runs processed.
+         */
+        private int nRuns = 0;
+
+        /**
+         * List of run numbers processed.
+         */
+        private final List<Integer> runsProcessed = new ArrayList<Integer>();
+
+        /**
+         * Set of unique detector objects.
+         */
+        private final Set<Detector> uniqueDetectorObjects = new HashSet<Detector>();
+
+        /**
+         * Set of unique run numbers processed.
+         */
+        private final Set<Integer> uniqueRuns = new LinkedHashSet<Integer>();
+
+        /**
+         * Hook for conditions changed used to test multiple run processing.
+         */
+        @Override
+        public void detectorChanged(final Detector detector) {
+            final int run = conditionsManager.getRun();
+            this.uniqueRuns.add(run);
+            this.runsProcessed.add(run);
+            ++this.nRuns;
+            ++this.nDetectorChanged;
+            this.uniqueDetectorObjects.add(detector);
+        }
+    }
+
+    /**
+     * Number of runs that should be processed in the job.
+     */
+    private static final int RUN_COUNT = 9;
 
     /**
      * Test file with a few events from each of the "good runs" of the 2012 Test Run.
@@ -30,12 +84,8 @@
     private static final String URL = "http://www.lcsim.org/test/hps-java/ConditionsTest.slcio";
 
     /**
-     * Number of runs that should be processed in the job.
-     */
-    private static final int RUN_COUNT = 9;
-
-    /**
      * Run the test.
+     * 
      * @throws Exception if there is a test error
      */
     public void test() throws Exception {
@@ -61,7 +111,7 @@
 
         // Print out unique runs.
         System.out.println("Unique run numbers in this job ...");
-        for (int runNumber : runNumberDriver.uniqueRuns) {
+        for (final int runNumber : runNumberDriver.uniqueRuns) {
             System.out.println(runNumber);
         }
 
@@ -69,7 +119,7 @@
 
         // Print out runs processed.
         System.out.println("Processed runs in order ...");
-        for (int runNumber : runNumberDriver.runsProcessed) {
+        for (final int runNumber : runNumberDriver.runsProcessed) {
             System.out.println(runNumber);
         }
 
@@ -80,59 +130,11 @@
         assertEquals("Number of unique runs was incorrect.", RUN_COUNT, runNumberDriver.uniqueRuns.size());
 
         // Check that detectorChanged was called the correct number of times.
-        assertEquals("The detectorChanged method was called an incorrect number of times.",
-                RUN_COUNT, runNumberDriver.nDetectorChanged);
+        assertEquals("The detectorChanged method was called an incorrect number of times.", RUN_COUNT,
+                runNumberDriver.nDetectorChanged);
 
         // Check that there was a unique Detector created for each run.
-        assertEquals("The number of Detector objects created was not correct.",
-                RUN_COUNT, runNumberDriver.uniqueDetectorObjects.size());
-    }
-
-    /**
-     * Simple Driver to store information about runs processed.
-     */
-    static class RunNumberDriver extends Driver {
-
-        /**
-         * Number of runs processed.
-         */
-        private int nRuns = 0;
-
-        /**
-         * Number of times {@link #detectorChanged(Detector)} was called.
-         */
-        private int nDetectorChanged = 0;
-
-        /**
-         * List of run numbers processed.
-         */
-        private List<Integer> runsProcessed = new ArrayList<Integer>();
-
-        /**
-         * Set of unique run numbers processed.
-         */
-        private Set<Integer> uniqueRuns = new LinkedHashSet<Integer>();
-
-        /**
-         * Set of unique detector objects.
-         */
-        private Set<Detector> uniqueDetectorObjects = new HashSet<Detector>();
-
-        /**
-         * Reference to conditions manager.
-         */
-        private static DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
-
-        /**
-         * Hook for conditions changed used to test multiple run processing.
-         */
-        public void detectorChanged(final Detector detector) {
-            final int run = conditionsManager.getRun();
-            uniqueRuns.add(run);
-            runsProcessed.add(run);
-            ++nRuns;
-            ++nDetectorChanged;
-            uniqueDetectorObjects.add(detector);
-        }
+        assertEquals("The number of Detector objects created was not correct.", RUN_COUNT,
+                runNumberDriver.uniqueDetectorObjects.size());
     }
 }

Modified: java/trunk/conditions/src/test/java/org/hps/conditions/beam/BeamConditionsTest.java
 =============================================================================
--- java/trunk/conditions/src/test/java/org/hps/conditions/beam/BeamConditionsTest.java	(original)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/beam/BeamConditionsTest.java	Wed Jul  8 14:47:40 2015
@@ -21,62 +21,27 @@
 /**
  * Load beam conditions for every run from the ECAL commissioning.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public final class BeamConditionsTest extends TestCase {
 
     /**
      * List of runs from the ECAL Eng Run.
      */
-    static int runs[] = new int[] {
-            2713, 2723, 2726, 2728, 2730, 2741, 2750, 2753, 2790, 2795, 2811,
-            2823, 2825, 2826, 2837, 2847, 2888, 2889, 2891, 2915, 2916, 3128,
-            3129, 3151, 3374, 3464, 2814, 2815, 3183, 3206, 3207, 3215, 3219,
-            3220, 3221, 3222, 3223, 3224, 3225, 3226, 3227, 3228, 3229, 3230,
-            3231, 3232, 3234, 3235, 3236, 3237, 3238, 3240, 3241, 3242, 3244,
-            3245, 3246, 3247, 3248, 3249, 3250, 3251, 3254, 3255, 3256, 3257,
-            3258, 3259, 3260, 3261, 3263, 3264, 3265, 3266, 3267, 3268, 3269,
-            3274, 3275, 3286, 3287, 3288, 3289, 3290, 3291, 3292, 3293, 3294,
-            3295, 3312, 3313, 3314, 3315, 3316, 3317, 3318, 3319, 3320, 3321,
-            3322, 3323, 3324, 3325, 3326, 3327, 3330, 3335, 3336, 3337, 3338,
-            3339, 3340, 3341, 3343, 3344, 3345, 3346, 3347, 3348, 3393, 3394,
-            3395, 3396, 3398, 3399, 3401, 3402, 3417, 3418, 3419, 3420, 3421,
-            3422, 3423, 3424, 3426, 3427, 3428, 3429, 3430, 3431, 3434, 3435,
-            3436, 3437, 3438, 3441, 3444, 3445, 3446, 3447, 3448, 3449, 3450,
-            3451, 3452, 3453, 3454, 3455, 3456, 3457, 3458, 3459, 3461, 3462,
-            3463, 3216, 2926, 2935, 2934, 2937 };
-
-    /**
-     * Test the beam conditions.
-     */
-    public void testBeamConditions() {
-        final DatabaseConditionsManager manager = DatabaseConditionsManager.getInstance();
-        manager.setLogLevel(Level.SEVERE);
-        System.out.println("run id current position_x position_y energy");
-        Map<Integer, BeamConditions> beamConditions = new LinkedHashMap<Integer, BeamConditions>();
-        for (int run : runs) {
-            try {
-                manager.setDetector("HPS-ECalCommissioning", run);
-            } catch (ConditionsNotFoundException e) {
-                throw new RuntimeException(e);
-            }
-            final BeamConditionsCollection beamCollection =
-                    manager.getCachedConditions(BeamConditionsCollection.class, "beam").getCachedData();
-            final BeamConditions beam = beamCollection.get(0);
-            System.out.print(run + " ");
-            System.out.print(beam.getRowId() + " ");
-            System.out.print(beam.getCurrent() + " ");
-            System.out.print(beam.getPositionX() + " ");
-            System.out.print(beam.getPositionY() + " ");
-            System.out.print(beam.getEnergy());
-            System.out.println();
-            beamConditions.put(run, beam);
-        }
-        writeBeamTuple(beamConditions);
-    }
+    static int runs[] = new int[] {2713, 2723, 2726, 2728, 2730, 2741, 2750, 2753, 2790, 2795, 2811, 2823, 2825, 2826,
+            2837, 2847, 2888, 2889, 2891, 2915, 2916, 3128, 3129, 3151, 3374, 3464, 2814, 2815, 3183, 3206, 3207, 3215,
+            3219, 3220, 3221, 3222, 3223, 3224, 3225, 3226, 3227, 3228, 3229, 3230, 3231, 3232, 3234, 3235, 3236, 3237,
+            3238, 3240, 3241, 3242, 3244, 3245, 3246, 3247, 3248, 3249, 3250, 3251, 3254, 3255, 3256, 3257, 3258, 3259,
+            3260, 3261, 3263, 3264, 3265, 3266, 3267, 3268, 3269, 3274, 3275, 3286, 3287, 3288, 3289, 3290, 3291, 3292,
+            3293, 3294, 3295, 3312, 3313, 3314, 3315, 3316, 3317, 3318, 3319, 3320, 3321, 3322, 3323, 3324, 3325, 3326,
+            3327, 3330, 3335, 3336, 3337, 3338, 3339, 3340, 3341, 3343, 3344, 3345, 3346, 3347, 3348, 3393, 3394, 3395,
+            3396, 3398, 3399, 3401, 3402, 3417, 3418, 3419, 3420, 3421, 3422, 3423, 3424, 3426, 3427, 3428, 3429, 3430,
+            3431, 3434, 3435, 3436, 3437, 3438, 3441, 3444, 3445, 3446, 3447, 3448, 3449, 3450, 3451, 3452, 3453, 3454,
+            3455, 3456, 3457, 3458, 3459, 3461, 3462, 3463, 3216, 2926, 2935, 2934, 2937};
 
     /**
      * Write out an AIDA tuple with the beam conditions.
+     *
      * @param beamConditions the beam conditions
      */
     private static void writeBeamTuple(final Map<Integer, BeamConditions> beamConditions) {
@@ -85,15 +50,15 @@
         final IAnalysisFactory analysisFactory = IAnalysisFactory.create();
         final ITree tree;
         try {
-            tree = analysisFactory.createTreeFactory().create(dir.getPath()
-                    + File.separator + "BeamTuple.aida", "xml", false, true);
+            tree = analysisFactory.createTreeFactory().create(dir.getPath() + File.separator + "BeamTuple.aida", "xml",
+                    false, true);
         } catch (IllegalArgumentException | IOException e) {
             throw new RuntimeException(e);
         }
-        final ITuple tuple = analysisFactory.createTupleFactory(tree).create("/Beam Tuple",
-                "Beam Tuple", "int run, double current, position_x, position_y, energy");
+        final ITuple tuple = analysisFactory.createTupleFactory(tree).create("/Beam Tuple", "Beam Tuple",
+                "int run, double current, position_x, position_y, energy");
         tuple.start();
-        for (Entry<Integer, BeamConditions> entry : beamConditions.entrySet()) {
+        for (final Entry<Integer, BeamConditions> entry : beamConditions.entrySet()) {
             tuple.addRow();
             Double current = entry.getValue().getCurrent();
             if (current == null) {
@@ -103,7 +68,7 @@
             if (positionX == null) {
                 positionX = 0.;
             }
-            Double positionY =  entry.getValue().getPositionY();
+            Double positionY = entry.getValue().getPositionY();
             if (positionY == null) {
                 positionY = 0.;
             }
@@ -120,8 +85,37 @@
         }
         try {
             tree.commit();
-        } catch (IOException e) {
+        } catch (final IOException e) {
             throw new RuntimeException(e);
         }
     }
+
+    /**
+     * Test the beam conditions.
+     */
+    public void testBeamConditions() {
+        final DatabaseConditionsManager manager = DatabaseConditionsManager.getInstance();
+        manager.setLogLevel(Level.SEVERE);
+        System.out.println("run id current position_x position_y energy");
+        final Map<Integer, BeamConditions> beamConditions = new LinkedHashMap<Integer, BeamConditions>();
+        for (final int run : runs) {
+            try {
+                manager.setDetector("HPS-ECalCommissioning", run);
+            } catch (final ConditionsNotFoundException e) {
+                throw new RuntimeException(e);
+            }
+            final BeamConditionsCollection beamCollection = manager.getCachedConditions(BeamConditionsCollection.class,
+                    "beam").getCachedData();
+            final BeamConditions beam = beamCollection.get(0);
+            System.out.print(run + " ");
+            System.out.print(beam.getRowId() + " ");
+            System.out.print(beam.getCurrent() + " ");
+            System.out.print(beam.getPositionX() + " ");
+            System.out.print(beam.getPositionY() + " ");
+            System.out.print(beam.getEnergy());
+            System.out.println();
+            beamConditions.put(run, beam);
+        }
+        writeBeamTuple(beamConditions);
+    }
 }

Modified: java/trunk/conditions/src/test/java/org/hps/conditions/beam/BeamCurrentTest.java
 =============================================================================
--- java/trunk/conditions/src/test/java/org/hps/conditions/beam/BeamCurrentTest.java	(original)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/beam/BeamCurrentTest.java	Wed Jul  8 14:47:40 2015
@@ -17,17 +17,47 @@
 /**
  * This test checks the Test Run beam current values by run.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public final class BeamCurrentTest extends TestCase {
+
+    /**
+     * This Driver will check the beam current for a run against the answer key.
+     */
+    static class BeamCurrentChecker extends Driver {
+
+        /**
+         * The current run number.
+         */
+        private int currentRun = Integer.MIN_VALUE;
+
+        /**
+         * This method will check the beam current against the answer key for the first event of a new run.
+         *
+         * @param the LCSim event
+         */
+        @Override
+        protected void process(final EventHeader event) {
+            if (this.currentRun != event.getRunNumber()) {
+                this.currentRun = event.getRunNumber();
+                final BeamCurrentCollection collection = DatabaseConditionsManager.getInstance()
+                        .getCachedConditions(BeamCurrentCollection.class, "beam_current").getCachedData();
+                final BeamCurrent beamCurrent = collection.iterator().next();
+                System.out.println("Run " + event.getRunNumber() + " has integrated beam current "
+                        + beamCurrent.getIntegratedBeamCurrent() + " nC.");
+                assertEquals("Wrong beam current for run.", ANSWER_KEY.get(this.currentRun),
+                        beamCurrent.getIntegratedBeamCurrent());
+            }
+        }
+    }
+
+    /** Answer key for beam current by run. */
+    private static final Map<Integer, Double> ANSWER_KEY = new HashMap<Integer, Double>();
 
     /**
      * This test file has a few events from the "good runs" of the Test Run.
      */
     private static final String URL = "http://www.lcsim.org/test/hps-java/ConditionsTest.slcio";
-
-    /** Answer key for beam current by run. */
-    private static final Map<Integer, Double> ANSWER_KEY = new HashMap<Integer, Double>();
 
     /** Setup the beam current answer key by run. */
     static {
@@ -63,33 +93,4 @@
         loop.add(new BeamCurrentChecker());
         loop.loop(-1, null);
     }
-
-    /**
-     * This Driver will check the beam current for a run against the answer key.
-     */
-    static class BeamCurrentChecker extends Driver {
-
-        /**
-         * The current run number.
-         */
-        private int currentRun = Integer.MIN_VALUE;
-
-        /**
-         * This method will check the beam current against the answer key for
-         * the first event of a new run.
-         * @param the LCSim event
-         */
-        protected void process(final EventHeader event) {
-            if (currentRun != event.getRunNumber()) {
-                currentRun = event.getRunNumber();
-                final BeamCurrentCollection collection = DatabaseConditionsManager.getInstance().getCachedConditions(
-                                BeamCurrentCollection.class, "beam_current").getCachedData();
-                final BeamCurrent beamCurrent = collection.iterator().next();
-                System.out.println("Run " + event.getRunNumber() + " has integrated beam current "
-                        + beamCurrent.getIntegratedBeamCurrent() + " nC.");
-                assertEquals("Wrong beam current for run.", ANSWER_KEY.get(currentRun),
-                        beamCurrent.getIntegratedBeamCurrent());
-            }
-        }
-    }
 }

Modified: java/trunk/conditions/src/test/java/org/hps/conditions/database/CollectionIdTest.java
 =============================================================================
--- java/trunk/conditions/src/test/java/org/hps/conditions/database/CollectionIdTest.java	(original)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/database/CollectionIdTest.java	Wed Jul  8 14:47:40 2015
@@ -7,10 +7,12 @@
 
 import junit.framework.TestCase;
 
+import org.hps.conditions.dummy.DummyConditionsObject.DummyConditionsObjectCollection;
+
 /**
  * Test adding a new collection and getting its unique ID.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public class CollectionIdTest extends TestCase {
 
@@ -43,10 +45,14 @@
      * @throws SQLException if there is an error executing SQL queries
      */
     public void testCollectionId() throws SQLException {
-        int collectionId = this.manager.addCollection("dummy", "test add", "foo bar baz");
+
+        final DummyConditionsObjectCollection collection = this.manager
+                .newCollection(DummyConditionsObjectCollection.class);
+
+        int collectionId = this.manager.getCollectionId(collection, "foo bar baz");
         System.out.println("created new collection " + collectionId);
 
-        collectionId = this.manager.addCollection("dummy", null, null);
+        collectionId = this.manager.getCollectionId(collection, null);
         System.out.println("created new collection " + collectionId);
     }
 }

Modified: java/trunk/conditions/src/test/java/org/hps/conditions/database/ConverterRegistryTest.java
 =============================================================================
--- java/trunk/conditions/src/test/java/org/hps/conditions/database/ConverterRegistryTest.java	(original)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/database/ConverterRegistryTest.java	Wed Jul  8 14:47:40 2015
@@ -5,7 +5,7 @@
 /**
  * This test loads the {@link ConverterRegistry}.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 // FIXME: Doesn't test anything.
 public final class ConverterRegistryTest extends TestCase {

Modified: java/trunk/conditions/src/test/java/org/hps/conditions/ecal/EcalLedTest.java
 =============================================================================
--- java/trunk/conditions/src/test/java/org/hps/conditions/ecal/EcalLedTest.java	(original)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/ecal/EcalLedTest.java	Wed Jul  8 14:47:40 2015
@@ -3,7 +3,7 @@
 import junit.framework.TestCase;
 
 import org.hps.conditions.database.DatabaseConditionsManager;
-//import org.hps.conditions.config.DevReadOnlyConfiguration;
+// import org.hps.conditions.config.DevReadOnlyConfiguration;
 import org.hps.conditions.ecal.EcalLed.EcalLedCollection;
 import org.hps.conditions.ecal.EcalLedCalibration.EcalLedCalibrationCollection;
 import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
@@ -11,7 +11,7 @@
 /**
  * A test to make sure ECAL LED information is readable from the conditions dev database.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public final class EcalLedTest extends TestCase {
 
@@ -33,7 +33,7 @@
         conditionsManager = DatabaseConditionsManager.getInstance();
         try {
             conditionsManager.setDetector("HPS-ECalCommissioning-v2", RUN_NUMBER);
-        } catch (ConditionsNotFoundException e) {
+        } catch (final ConditionsNotFoundException e) {
             throw new RuntimeException(e);
         }
     }
@@ -44,9 +44,9 @@
     public void testEcalLed() {
 
         // LED channel information.
-        final EcalLedCollection leds = conditionsManager.getCachedConditions(
-                EcalLedCollection.class, "ecal_leds").getCachedData();
-        for (EcalLed led : leds) {
+        final EcalLedCollection leds = conditionsManager.getCachedConditions(EcalLedCollection.class, "ecal_leds")
+                .getCachedData();
+        for (final EcalLed led : leds) {
             System.out.println(led);
         }
 

Modified: java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtBadChannelTest.java
 =============================================================================
--- java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtBadChannelTest.java	(original)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtBadChannelTest.java	Wed Jul  8 14:47:40 2015
@@ -20,14 +20,56 @@
 /**
  * This class tests that the correct bad channel conditions are found for the test run.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public final class SvtBadChannelTest extends TestCase {
 
     /**
-     * This test file has a few events from each of the "good runs" of the 2012 Test Run.
+     * This Driver will check the number of bad channels for a run against the answer key.
      */
-    private static final String TEST_FILE_URL = "http://www.lcsim.org/test/hps/conditions_test.slcio";
+    static class SvtBadChannelChecker extends Driver {
+
+        /**
+         * The current run number.
+         */
+        private int currentRun = -1;
+
+        /**
+         * This method will check the number of bad channels against the answer key for the first event of a new run.
+         * 
+         * @param the LCSim event
+         */
+        @Override
+        public void process(final EventHeader event) {
+            final int run = event.getRunNumber();
+            if (run != this.currentRun) {
+                this.currentRun = run;
+                final Detector detector = event.getDetector();
+                int badChannels = 0;
+                final List<HpsSiSensor> sensors = detector.getDetectorElement().findDescendants(HpsSiSensor.class);
+                for (final HpsSiSensor sensor : sensors) {
+                    final int nchannels = sensor.getNumberOfChannels();
+                    for (int i = 0; i < nchannels; i++) {
+                        if (sensor.isBadChannel(i)) {
+                            ++badChannels;
+                        }
+                    }
+                }
+                System.out.println("Run " + this.currentRun + " has " + badChannels + " SVT bad channels.");
+                if (ANSWER_KEY.containsKey(this.currentRun)) {
+                    final Integer badChannelsExpected = ANSWER_KEY.get(run);
+                    TestCase.assertEquals("Wrong number of bad channels found.", (int) badChannelsExpected, badChannels);
+                } else {
+                    TestCase.assertEquals("Wrong number of bad channels found.", BAD_CHANNELS_QA_ANSWER, badChannels);
+                }
+            }
+        }
+    }
+
+    /**
+     * Answer key for number of bad channels per run.
+     */
+    private static final Map<Integer, Integer> ANSWER_KEY = new HashMap<Integer, Integer>();
 
     /**
      * This is the number of bad channels in the conditions set that covers all run numbers.
@@ -35,9 +77,9 @@
     private static final int BAD_CHANNELS_QA_ANSWER = 50;
 
     /**
-     * Answer key for number of bad channels per run.
+     * This test file has a few events from each of the "good runs" of the 2012 Test Run.
      */
-    private static final Map<Integer, Integer> ANSWER_KEY = new HashMap<Integer, Integer>();
+    private static final String TEST_FILE_URL = "http://www.lcsim.org/test/hps/conditions_test.slcio";
 
     /**
      * Setup the answer key.
@@ -53,6 +95,7 @@
 
     /**
      * Run the test.
+     * 
      * @throws Exception if there is an event processing error
      */
     public void test() throws Exception {
@@ -74,48 +117,4 @@
         // Run over all events.
         loop.loop(-1, null);
     }
-
-    /**
-     * This Driver will check the number of bad channels for a run against the answer key.
-     */
-    static class SvtBadChannelChecker extends Driver {
-
-        /**
-         * The current run number.
-         */
-        private int currentRun = -1;
-
-        /**
-         * This method will check the number of bad channels against the answer
-         * key for the first event of a new run.
-         * @param the LCSim event
-         */
-        public void process(final EventHeader event) {
-            final int run = event.getRunNumber();
-            if (run != currentRun) {
-                currentRun = run;
-                final Detector detector = event.getDetector();
-                int badChannels = 0;
-                final List<HpsSiSensor> sensors = detector.getDetectorElement()
-                        .findDescendants(HpsSiSensor.class);
-                for (final HpsSiSensor sensor : sensors) {
-                    final int nchannels = sensor.getNumberOfChannels();
-                    for (int i = 0; i < nchannels; i++) {
-                        if (sensor.isBadChannel(i)) {
-                            ++badChannels;
-                        }
-                    }
-                }
-                System.out.println("Run " + currentRun + " has " + badChannels + " SVT bad channels.");
-                if (ANSWER_KEY.containsKey(currentRun)) {
-                    final Integer badChannelsExpected = ANSWER_KEY.get(run);
-                    TestCase.assertEquals("Wrong number of bad channels found.",
-                            (int) badChannelsExpected, (int) badChannels);
-                } else {
-                    TestCase.assertEquals("Wrong number of bad channels found.",
-                            (int) BAD_CHANNELS_QA_ANSWER, (int) badChannels);
-                }
-            }
-        }
-    }
 }

Modified: java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtConfigurationTest.java
 =============================================================================
--- java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtConfigurationTest.java	(original)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtConfigurationTest.java	Wed Jul  8 14:47:40 2015
@@ -12,7 +12,7 @@
 /**
  * Load an SVT XML configuration from the database.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public final class SvtConfigurationTest extends TestCase {
 

Modified: java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtDaqMappingTest.java
 =============================================================================
--- java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtDaqMappingTest.java	(original)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtDaqMappingTest.java	Wed Jul  8 14:47:40 2015
@@ -6,12 +6,22 @@
 import org.hps.conditions.svt.SvtDaqMapping.SvtDaqMappingCollection;
 
 /**
- * This test checks if the SVT DAQ map was loaded with reasonable values and is
- * being read correctly from the conditions database.
+ * This test checks if the SVT DAQ map was loaded with reasonable values and is being read correctly from the conditions
+ * database.
  *
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Omar Moreno, UCSC
  */
 public final class SvtDaqMappingTest extends TestCase {
+
+    /**
+     * Maximum FEB Hybrid ID.
+     */
+    public static final int MAX_FEB_HYBRID_ID = 3;
+
+    /**
+     * Minimum FEB Hybrid ID.
+     */
+    public static final int MIN_FEB_HYBRID_ID = 0;
 
     /**
      * Total number of SVT sensors.
@@ -19,18 +29,8 @@
     public static final int TOTAL_NUMBER_OF_SENSORS = 36;
 
     /**
-     * Minimum FEB Hybrid ID.
-     */
-    public static final int MIN_FEB_HYBRID_ID = 0;
-
-    /**
-     * Maximum FEB Hybrid ID.
-     */
-    public static final int MAX_FEB_HYBRID_ID = 3;
-
-
-    /**
      * Load the DAQ map from the database.
+     *
      * @throws Exception if there is a test error
      */
     public void test() throws Exception {
@@ -40,25 +40,17 @@
                 SvtDaqMappingCollection.class, "svt_daq_map").getCachedData();
         int totalSensors = 0;
         int febHybridID;
-        //this.printDebug("");
-        for (SvtDaqMapping daqMapping : daqMappingCollection) {
-            //this.printDebug("Sensor: \n" + daqMapping.toString());
+        // this.printDebug("");
+        for (final SvtDaqMapping daqMapping : daqMappingCollection) {
+            // this.printDebug("Sensor: \n" + daqMapping.toString());
             // Check that the FEB Hybrid ID is within the allowable limits
             febHybridID = daqMapping.getFebHybridID();
-            assertTrue("FEB Hybrid ID is out of range!.",
-                    febHybridID >= MIN_FEB_HYBRID_ID && febHybridID <= MAX_FEB_HYBRID_ID);
+            assertTrue("FEB Hybrid ID is out of range!.", febHybridID >= MIN_FEB_HYBRID_ID
+                    && febHybridID <= MAX_FEB_HYBRID_ID);
             totalSensors++;
         }
-        //this.printDebug("Total number of sensors found: " + totalSensors);
+        // this.printDebug("Total number of sensors found: " + totalSensors);
         assertTrue(totalSensors == TOTAL_NUMBER_OF_SENSORS);
 
     }
-
-    /**
-     * Print debug message.
-     * @param debugMessage the message
-     */
-    private void printDebug(final String debugMessage) {
-        System.out.println(this.getClass().getSimpleName() + ":: " + debugMessage);
-    }
 }

Modified: java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtDetectorSetupTest.java
 =============================================================================
--- java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtDetectorSetupTest.java	(original)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtDetectorSetupTest.java	Wed Jul  8 14:47:40 2015
@@ -9,15 +9,34 @@
 import org.lcsim.geometry.Detector;
 
 /**
- * This test loads {@link SvtConditions} data onto the detector and then checks
- * that all channels of each sensor have non-zero data values for applicable
- * parameters.
+ * This test loads {@link SvtConditions} data onto the detector and then checks that all channels of each sensor have
+ * non-zero data values for applicable parameters.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Jeremy McCormick, SLAC
+ * @author Omar Moreno, UCSC
  */
 // TODO: Update this test with more meaningful assertions.
 public final class SvtDetectorSetupTest extends TestCase {
+
+    /**
+     * Maximum channel number.
+     */
+    public static final int MAX_CHANNEL_NUMBER = 639;
+
+    /**
+     * Maximum FEB Hybrid ID.
+     */
+    public static final int MAX_FEB_HYBRID_ID = 3;
+
+    /**
+     * Maximum FEB ID.
+     */
+    public static final int MAX_FEB_ID = 9;
+
+    /**
+     * Name of SVT subdetector.
+     */
+    public static final String SVT_SUBDETECTOR_NAME = "Tracker";
 
     /**
      * Total number of SVT sensors.
@@ -25,27 +44,17 @@
     public static final int TOTAL_NUMBER_OF_SENSORS = 36;
 
     /**
-     * Maximum FEB ID.
+     * Print debug message.
+     * 
+     * @param debugMessage the message
      */
-    public static final int MAX_FEB_ID = 9;
-
-    /**
-     * Maximum FEB Hybrid ID.
-     */
-    public static final int MAX_FEB_HYBRID_ID = 3;
-
-    /**
-     * Maximum channel number.
-     */
-    public static final int MAX_CHANNEL_NUMBER = 639;
-
-    /**
-     * Name of SVT subdetector.
-     */
-    public static final String SVT_SUBDETECTOR_NAME = "Tracker";
+    private void printDebug(final String debugMessage) {
+        System.out.println(this.getClass().getSimpleName() + ":: " + debugMessage);
+    }
 
     /**
      * Load SVT conditions data onto the detector and then perform basic checks.
+     * 
      * @throws Exception if there is a test error
      */
     public void test() throws Exception {
@@ -57,8 +66,8 @@
         final Detector detector = conditionsManager.getCachedConditions(Detector.class, "compact.xml").getCachedData();
 
         // Get all SVT conditions.
-        final SvtConditions conditions = conditionsManager.getCachedConditions(
-                SvtConditions.class, "svt_conditions").getCachedData();
+        final SvtConditions conditions = conditionsManager.getCachedConditions(SvtConditions.class, "svt_conditions")
+                .getCachedData();
 
         // Load the SVT conditions onto detector.
         final SvtDetectorSetup loader = new SvtDetectorSetup("Tracker");
@@ -74,7 +83,7 @@
 
         // Loop over sensors.
         int totalSensors = 0;
-        for (HpsSiSensor sensor : sensors) {
+        for (final HpsSiSensor sensor : sensors) {
 
             final int nChannels = sensor.getNumberOfChannels();
             assertTrue("The number of channels this sensor has is invalid", nChannels <= MAX_CHANNEL_NUMBER);
@@ -86,8 +95,8 @@
             assertTrue("FEB ID is invalid.  The FEB ID should be less than " + MAX_FEB_ID, febID <= MAX_FEB_ID);
 
             final int febHybridID = sensor.getFebHybridID();
-            assertTrue("FEB Hybrid ID is invalid.  The FEB Hybrid ID should be less than "
-                    + MAX_FEB_HYBRID_ID, febHybridID <= MAX_FEB_HYBRID_ID);
+            assertTrue("FEB Hybrid ID is invalid.  The FEB Hybrid ID should be less than " + MAX_FEB_HYBRID_ID,
+                    febHybridID <= MAX_FEB_HYBRID_ID);
 
             for (int channel = 0; channel < nChannels; channel++) {
 
@@ -106,12 +115,4 @@
 
         System.out.println("Successfully loaded conditions data onto " + totalSensors + " SVT sensors!");
     }
-
-    /**
-     * Print debug message.
-     * @param debugMessage the message
-     */
-    private void printDebug(String debugMessage) {
-        System.out.println(this.getClass().getSimpleName() + ":: " + debugMessage);
-    }
 }

Modified: java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtTimingConstantsTest.java
 =============================================================================
--- java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtTimingConstantsTest.java	(original)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtTimingConstantsTest.java	Wed Jul  8 14:47:40 2015
@@ -11,7 +11,7 @@
 /**
  * Read SVT timing constants from the conditions database.
  *
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
  */
 public class SvtTimingConstantsTest extends TestCase {
 
@@ -23,9 +23,9 @@
     /**
      * This is a list of run start values to check.
      */
-    private static final int[] RUNS = new int[] {4871, 5038, 5076, 5139, 5174, 5218, 5236, 5251, 5263, 5299, 5310, 5375, 5400, 5533, 5558, 5575,
-            5596, 5601, 5603, 5610, 4871, 5038, 5076, 5139, 5174, 5218, 5236, 5251, 5263, 5299, 5310, 5375, 5400, 5533, 5558, 5575, 5596, 5601, 5603,
-            5610, 5640, 5641, 5642, 5686, 5722, 5779};
+    private static final int[] RUNS = new int[] {4871, 5038, 5076, 5139, 5174, 5218, 5236, 5251, 5263, 5299, 5310,
+            5375, 5400, 5533, 5558, 5575, 5596, 5601, 5603, 5610, 4871, 5038, 5076, 5139, 5174, 5218, 5236, 5251, 5263,
+            5299, 5310, 5375, 5400, 5533, 5558, 5575, 5596, 5601, 5603, 5610, 5640, 5641, 5642, 5686, 5722, 5779};
 
     /**
      * Load SVT timing constants and print them out by run range.
@@ -38,11 +38,12 @@
         // manager.setConnectionResource("/org/hps/conditions/config/jeremym_dev_connection.prop");
         for (final int run : RUNS) {
             manager.setDetector(DETECTOR, run);
-            final SvtTimingConstantsCollection collection = manager.getCachedConditions(SvtTimingConstantsCollection.class, "svt_timing_constants")
-                    .getCachedData();
+            final SvtTimingConstantsCollection collection = manager.getCachedConditions(
+                    SvtTimingConstantsCollection.class, "svt_timing_constants").getCachedData();
             final ConditionsRecord condi = manager.findConditionsRecords("svt_timing_constants").get(0);
-            System.out.println("run_start: " + condi.getRunStart() + ", run_end: " + condi.getRunEnd() + ", offset_phase: "
-                    + collection.get(0).getOffsetPhase() + ", offset_time: " + collection.get(0).getOffsetTime());
+            System.out.println("run_start: " + condi.getRunStart() + ", run_end: " + condi.getRunEnd()
+                    + ", offset_phase: " + collection.get(0).getOffsetPhase() + ", offset_time: "
+                    + collection.get(0).getOffsetTime());
         }
     }
 }

Modified: java/trunk/conditions/src/test/java/org/hps/conditions/svt/TestRunSvtBadChannelsTest.java
 =============================================================================
--- java/trunk/conditions/src/test/java/org/hps/conditions/svt/TestRunSvtBadChannelsTest.java	(original)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/svt/TestRunSvtBadChannelsTest.java	Wed Jul  8 14:47:40 2015
@@ -11,54 +11,39 @@
 import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
 
 /**
- * This test reads Test Run bad channel collections from the database
- * using a conditions series and checks that the correct number
- * of channels are flagged using several different runs.
+ * This test reads Test Run bad channel collections from the database using a conditions series and checks that the
+ * correct number of channels are flagged using several different runs.
  *
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
  */
 public final class TestRunSvtBadChannelsTest extends TestCase {
 
     /*
-    mysql> select run_start, run_end, name from conditions where table_name like 'test_run_svt_bad_channels';
-    +-----------+---------+---------------------------+
-    | run_start | run_end | name                      |
-    +-----------+---------+---------------------------+
-    |         0 |    1365 | test_run_svt_bad_channels |
-    |      1351 |    1351 | test_run_svt_bad_channels |
-    |      1353 |    1353 | test_run_svt_bad_channels |
-    |      1354 |    1354 | test_run_svt_bad_channels |
-    |      1358 |    1358 | test_run_svt_bad_channels |
-    |      1359 |    1359 | test_run_svt_bad_channels |
-    |      1360 |    1360 | test_run_svt_bad_channels |
-    +-----------+---------+---------------------------+
-    */
+     * mysql> select collection_id, count(*) from test_run_svt_bad_channels group by collection_id;
+     * +---------------+----------+ | collection_id | count(*) | +---------------+----------+ | 1 | 50 | | 2 | 392 | | 3
+     * | 427 | | 4 | 457 | | 5 | 298 | | 6 | 424 | | 7 | 424 | +---------------+----------+
+     */
+    /**
+     * The bad channel count for each run.
+     */
+    private static int[] BAD_CHANNEL_COUNTS = {50, 392, 427, 457, 298, 424, 424};
+
+    /*
+     * mysql> select run_start, run_end, name from conditions where table_name like 'test_run_svt_bad_channels';
+     * +-----------+---------+---------------------------+ | run_start | run_end | name |
+     * +-----------+---------+---------------------------+ | 0 | 1365 | test_run_svt_bad_channels | | 1351 | 1351 |
+     * test_run_svt_bad_channels | | 1353 | 1353 | test_run_svt_bad_channels | | 1354 | 1354 | test_run_svt_bad_channels
+     * | | 1358 | 1358 | test_run_svt_bad_channels | | 1359 | 1359 | test_run_svt_bad_channels | | 1360 | 1360 |
+     * test_run_svt_bad_channels | +-----------+---------+---------------------------+
+     */
     /**
      * The run numbers to check.
      */
     private static final int[] RUN_NUMBERS = new int[] {0, 1351, 1353, 1354, 1358, 1359, 1360};
 
-    /*
-    mysql> select collection_id, count(*) from test_run_svt_bad_channels group by collection_id;
-    +---------------+----------+
-    | collection_id | count(*) |
-    +---------------+----------+
-    |             1 |       50 |
-    |             2 |      392 |
-    |             3 |      427 |
-    |             4 |      457 |
-    |             5 |      298 |
-    |             6 |      424 |
-    |             7 |      424 |
-    +---------------+----------+
-    */
-    /**
-     * The bad channel count for each run.
-     */
-    private static int[] BAD_CHANNEL_COUNTS = {50, 392, 427, 457, 298, 424, 424};
-
     /**
      * Test the bad channel numbers for various runs of the Test Run.
+     * 
      * @throws ConditionsNotFoundException if there is a conditions error
      */
     public void testSvtBadChannels() throws ConditionsNotFoundException {
@@ -69,7 +54,7 @@
 
         for (int i = 0; i < RUN_NUMBERS.length; i++) {
 
-            int runNumber = RUN_NUMBERS[i];
+            final int runNumber = RUN_NUMBERS[i];
 
             System.out.println("-------------");
             System.out.println("Run #" + runNumber);
@@ -78,12 +63,12 @@
 
             conditionsManager.setDetector("HPS-TestRun-v5", runNumber);
 
-            final ConditionsSeries<SvtBadChannel, SvtBadChannelCollection> series =
-                    conditionsManager.getConditionsSeries(SvtBadChannelCollection.class, "test_run_svt_bad_channels");
+            final ConditionsSeries<SvtBadChannel, SvtBadChannelCollection> series = conditionsManager
+                    .getConditionsSeries(SvtBadChannelCollection.class, "test_run_svt_bad_channels");
 
             int totalBadChannels = 0;
-            for (ConditionsObjectCollection<SvtBadChannel> collection : series) {
-                //System.out.println(collection.getConditionsRecord());
+            for (final ConditionsObjectCollection<SvtBadChannel> collection : series) {
+                // System.out.println(collection.getConditionsRecord());
                 totalBadChannels += collection.size();
             }
             System.out.println("found " + totalBadChannels + " total bad channels");

Modified: java/trunk/conditions/src/test/java/org/hps/conditions/svt/TestRunSvtConditionsConverterTest.java
 =============================================================================
--- java/trunk/conditions/src/test/java/org/hps/conditions/svt/TestRunSvtConditionsConverterTest.java	(original)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/svt/TestRunSvtConditionsConverterTest.java	Wed Jul  8 14:47:40 2015
@@ -7,7 +7,7 @@
 /**
  * Create combined SVT conditions for Test Run.
  *
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Jeremy McCormick, SLAC
  */
 public final class TestRunSvtConditionsConverterTest extends TestCase {
 
@@ -18,6 +18,7 @@
 
     /**
      * Create combined SVT Test Run conditions.
+     * 
      * @throws Exception if there is a conditions system error
      */
     public void test() throws Exception {

Modified: java/trunk/conditions/src/test/java/org/hps/conditions/svt/TestRunSvtDaqMappingTest.java
 =============================================================================
--- java/trunk/conditions/src/test/java/org/hps/conditions/svt/TestRunSvtDaqMappingTest.java	(original)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/svt/TestRunSvtDaqMappingTest.java	Wed Jul  8 14:47:40 2015
@@ -6,12 +6,42 @@
 import org.hps.conditions.svt.TestRunSvtDaqMapping.TestRunSvtDaqMappingCollection;
 
 /**
- * This test checks if the test run SVT DAQ map was loaded with reasonable
- * values and is being read correctly from the conditions database.
+ * This test checks if the test run SVT DAQ map was loaded with reasonable values and is being read correctly from the
+ * conditions database.
  *
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Jeremy McCormick, SLAC
  */
 public final class TestRunSvtDaqMappingTest extends TestCase {
+
+    /**
+     * Maximum FPGA ID.
+     */
+    private static final int MAX_FPGA_ID = 6;
+
+    /**
+     * Maximum Hybrid ID.
+     */
+    private static final int MAX_HYBRID_ID = 2;
+
+    /**
+     * Maximum layer number.
+     */
+    private static final int MAX_LAYER_NUMBER = 10;
+
+    /**
+     * Minimum FPGA ID.
+     */
+    private static final int MIN_FPGA_ID = 0;
+
+    /**
+     * Minimum Hybrid ID.
+     */
+    private static final int MIN_HYBRID_ID = 0;
+
+    /**
+     * Minimum layer number.
+     */
+    private static final int MIN_LAYER_NUMBER = 1;
 
     /**
      * The run number to use for the test.
@@ -24,37 +54,17 @@
     private static final int TOTAL_NUMBER_OF_SENSORS = 20;
 
     /**
-     * Minimum FPGA ID.
+     * Print debug message.
+     *
+     * @param debugMessage the message
      */
-    private static final int MIN_FPGA_ID = 0;
-
-    /**
-     * Maximum FPGA ID.
-     */
-    private static final int MAX_FPGA_ID = 6;
-
-    /**
-     * Minimum Hybrid ID.
-     */
-    private static final int MIN_HYBRID_ID = 0;
-
-    /**
-     * Maximum Hybrid ID.
-     */
-    private static final int MAX_HYBRID_ID = 2;
-
-    /**
-     * Minimum layer number.
-     */
-    private static final int MIN_LAYER_NUMBER = 1;
-
-    /**
-     * Maximum layer number.
-     */
-    private static final int MAX_LAYER_NUMBER = 10;
+    private void printDebug(final String debugMessage) {
+        System.out.println("[ " + this.getClass().getSimpleName() + " ]: " + debugMessage);
+    }
 
     /**
      * Perform checks of SVT DAQ mapping for Test Run.
+     *
      * @throws Exception if there is a test or conditions error
      */
     public void test() throws Exception {
@@ -68,7 +78,7 @@
 
         int totalSensors = 0;
         this.printDebug("");
-        for (TestRunSvtDaqMapping daqMapping : daqMappingCollection) {
+        for (final TestRunSvtDaqMapping daqMapping : daqMappingCollection) {
 
             this.printDebug("Sensor: \n" + daqMapping.toString());
 
@@ -78,13 +88,13 @@
 
             // Check that the Hybrid ID is within the allowable limits
             final int hybridID = daqMapping.getHybridID();
-            assertTrue("Hybrid ID " + hybridID + " is out of range!",
-                    hybridID >= MIN_HYBRID_ID && hybridID <= MAX_HYBRID_ID);
+            assertTrue("Hybrid ID " + hybridID + " is out of range!", hybridID >= MIN_HYBRID_ID
+                    && hybridID <= MAX_HYBRID_ID);
 
             // Check that the layer number is within the allowable limits
             final int layerNumber = daqMapping.getLayerNumber();
-            assertTrue("The layer number " + layerNumber + " is out of range!",
-                    layerNumber >= MIN_LAYER_NUMBER && layerNumber <= MAX_LAYER_NUMBER);
+            assertTrue("The layer number " + layerNumber + " is out of range!", layerNumber >= MIN_LAYER_NUMBER
+                    && layerNumber <= MAX_LAYER_NUMBER);
 
             totalSensors++;
         }
@@ -92,12 +102,4 @@
         this.printDebug("Total number of sensors found: " + totalSensors);
         assertTrue(totalSensors == TOTAL_NUMBER_OF_SENSORS);
     }
-
-    /**
-     * Print debug message.
-     * @param debugMessage the message
-     */
-    private void printDebug(final String debugMessage) {
-        System.out.println("[ " + this.getClass().getSimpleName() + " ]: " + debugMessage);
-    }
 }

Modified: java/trunk/conditions/src/test/java/org/hps/conditions/svt/TestRunSvtDetectorSetupTest.java
 =============================================================================
--- java/trunk/conditions/src/test/java/org/hps/conditions/svt/TestRunSvtDetectorSetupTest.java	(original)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/svt/TestRunSvtDetectorSetupTest.java	Wed Jul  8 14:47:40 2015
@@ -9,23 +9,17 @@
 import org.lcsim.geometry.Detector;
 
 /**
- * This test loads {@link TestRunSvtConditions} data onto the detector and then
- * checks that all channels of each sensor have non-zero data values for
- * applicable parameters.
+ * This test loads {@link TestRunSvtConditions} data onto the detector and then checks that all channels of each sensor
+ * have non-zero data values for applicable parameters.
  *
- * @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
+ * @author Omar Moreno, UCSC
  */
 public final class TestRunSvtDetectorSetupTest extends TestCase {
 
     /**
-     * Run number to use for test.
+     * Maximum channel number.
      */
-    private static final int RUN_NUMBER = 1351;
-
-    /**
-     * Total number of SVT sensors.
-     */
-    private static final int TOTAL_NUMBER_OF_SENSORS = 20;
+    private static final int MAX_CHANNEL_NUMBER = 639;
 
     /**
      * Maximum FPGA ID.
@@ -38,9 +32,9 @@
     private static final int MAX_HYBRID_ID = 2;
 
     /**
-     * Maximum channel number.
+     * Run number to use for test.
      */
-    private static final int MAX_CHANNEL_NUMBER = 639;
+    private static final int RUN_NUMBER = 1351;
 
     /**
      * Name of SVT subdetector.
@@ -48,7 +42,22 @@
     private static final String SVT_SUBDETECTOR_NAME = "Tracker";
 
     /**
+     * Total number of SVT sensors.
+     */
+    private static final int TOTAL_NUMBER_OF_SENSORS = 20;
+
+    /**
+     * Print debug message.
+     * 
+     * @param debugMessage the message
+     */
+    private void printDebug(final String debugMessage) {
+        System.out.println(this.getClass().getSimpleName() + ":: " + debugMessage);
+    }
+
+    /**
      * Load SVT conditions data onto the detector and then perform basic checks of channel conditions data.
+     * 
      * @throws Exception if there is a test error
      */
     public void test() throws Exception {
@@ -70,7 +79,7 @@
 
         // Loop over sensors.
         int totalSensors = 0;
-        for (HpsTestRunSiSensor sensor : sensors) {
+        for (final HpsTestRunSiSensor sensor : sensors) {
 
             final int nChannels = sensor.getNumberOfChannels();
             assertTrue("The number of channels this sensor has is invalid", nChannels <= MAX_CHANNEL_NUMBER);
@@ -82,8 +91,8 @@
             assertTrue("FPGA ID is invalid.  The FPGA ID should be less than " + MAX_FPGA_ID, fpgaID <= MAX_FPGA_ID);
 
             final int hybridID = sensor.getHybridID();
-            assertTrue("Hybrid ID is invalid.  The Hybrid ID should be less than "
-                    + MAX_HYBRID_ID, hybridID <= MAX_HYBRID_ID);
+            assertTrue("Hybrid ID is invalid.  The Hybrid ID should be less than " + MAX_HYBRID_ID,
+                    hybridID <= MAX_HYBRID_ID);
 
             for (int channel = 0; channel < nChannels; channel++) {
 
@@ -103,12 +112,4 @@
         System.out.println("Successfully loaded test run conditions data onto " + totalSensors + " SVT sensors!");
     }
 
-    /**
-     * Print debug message.
-     * @param debugMessage the message
-     */
-    private void printDebug(String debugMessage) {
-        System.out.println(this.getClass().getSimpleName() + ":: " + debugMessage);
-    }
-
 }

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalCalibrationsDriver.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalCalibrationsDriver.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalCalibrationsDriver.java	Wed Jul  8 14:47:40 2015
@@ -20,9 +20,10 @@
 
 import org.hps.conditions.api.ConditionsObjectException;
 import org.hps.conditions.api.ConditionsRecord;
-import org.hps.conditions.api.FieldValueMap;
+import org.hps.conditions.api.DatabaseObjectException;
+import org.hps.conditions.api.FieldValues;
+import org.hps.conditions.api.TableMetaData;
 import org.hps.conditions.database.DatabaseConditionsManager;
-import org.hps.conditions.database.TableMetaData;
 import org.hps.conditions.ecal.EcalCalibration;
 import org.hps.conditions.ecal.EcalCalibration.EcalCalibrationCollection;
 import org.hps.conditions.ecal.EcalChannel;
@@ -220,7 +221,11 @@
             
             // Create a new calibration object and add it to the collection, using mean for pedestal
             // and sigma for noise.
-            calibrations.add(new EcalCalibration(channelId, mean, sigma));
+            try {
+            	calibrations.add(new EcalCalibration(channelId, mean, sigma));
+            } catch (ConditionsObjectException e) {
+            	throw new RuntimeException("Error adding new calibration object.", e);
+            }
         } 
         
         // Get the list of field names for the header.
@@ -259,9 +264,9 @@
             StringBuffer buff = new StringBuffer(fieldNames);
             buff.append('\n');
             for (EcalCalibration calibration : calibrations) {
-                FieldValueMap fieldValues = calibration.getFieldValues();
-                for (String field : fieldValues.keySet()) {
-                    buff.append(fieldValues.get(field) + " ");
+                FieldValues fieldValues = calibration.getFieldValues();
+                for (String field : fieldValues.getFieldNames()) {
+                    buff.append(fieldValues.getValue(field) + " ");
                 }
                 buff.setLength(buff.length() - 1);
                 buff.append('\n');
@@ -288,7 +293,7 @@
     private void loadCalibrations(EcalCalibrationCollection calibrations) {
         int collectionId = -1;
         try {
-            conditionsManager.addCollection(ECAL_CALIBRATIONS, "EcalCalibrationsDriver added by " + System.getProperty("user.name"), null);
+            conditionsManager.getCollectionId(calibrations, "loaded by EcalCalibrationsDriver");
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
@@ -304,7 +309,7 @@
                     "Generated by EcalCalibrationsDriver.", 
                     "eng_run");
             conditionsRecord.insert();
-        } catch (ConditionsObjectException | SQLException e) {
+        } catch (DatabaseObjectException | SQLException e) {
             throw new RuntimeException(e);
         }
     }

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalPedestalCalculator.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalPedestalCalculator.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalPedestalCalculator.java	Wed Jul  8 14:47:40 2015
@@ -12,8 +12,9 @@
 
 import org.hps.conditions.api.ConditionsObjectException;
 import org.hps.conditions.api.ConditionsRecord;
+import org.hps.conditions.api.DatabaseObjectException;
+import org.hps.conditions.api.TableMetaData;
 import org.hps.conditions.database.DatabaseConditionsManager;
-import org.hps.conditions.database.TableMetaData;
 import org.hps.conditions.ecal.EcalCalibration;
 import org.hps.conditions.ecal.EcalCalibration.EcalCalibrationCollection;
 import org.hps.conditions.ecal.EcalChannel;
@@ -114,7 +115,11 @@
             }
         }
         if (uploadToDB) {
-            uploadToDB();
+        	try {
+        		uploadToDB();
+        	} catch (DatabaseObjectException | ConditionsObjectException | SQLException e) {
+        		throw new RuntimeException("Error uploading to database.", e);
+        	}
         } else {
             System.out.println("!!!!!!!!!!!!!!!!!!!!!!! Not Writing Database !!!!!!!!!!!!!!!!!!!!!!!!!!");
         }
@@ -141,7 +146,7 @@
         return String.format(histoNameFormat,cc.getChannelId());
     }
 
-    private void uploadToDB() {
+    private void uploadToDB() throws DatabaseObjectException, ConditionsObjectException, SQLException {
         System.out.println(String.format("Uploading new pedestals to the database, runMin=%d, runMax=%d, tag=%s ....",
                 runNumber,runNumberMax,dbTag));
       
@@ -163,25 +168,20 @@
 
         int collectionId = -1;
         try {
-            collectionId = conditionsManager.addCollection(dbTableName, "EcalPedestalCalculator added by " + System.getProperty("user.name"), null);
+            collectionId = conditionsManager.getCollectionId(calibrations, "loaded by EcalPedestalCalculator");
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
-        try {
-            calibrations.setCollectionId(collectionId);
+        calibrations.setCollectionId(collectionId);
             
-            System.err.println("CollectionID:  "+collectionId);
-
-            calibrations.insert();
+        System.err.println("CollectionID:  "+collectionId);
+
+        calibrations.insert();
             ConditionsRecord conditionsRecord = new ConditionsRecord(
                     calibrations.getCollectionId(), runNumber, runNumberMax, dbTableName, dbTableName, 
                     "Generated by EcalPedestalCalculator from Run #"+runNumber, dbTag);
             conditionsRecord.insert();
-            
-        } catch (ConditionsObjectException | SQLException e) {
-            throw new RuntimeException(e);
-        }
-        
+                   
     }
     
     private void writeFileForDB(String outputFilePrefix) {

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsCollectionTableModel.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsCollectionTableModel.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsCollectionTableModel.java	Wed Jul  8 14:47:40 2015
@@ -4,8 +4,8 @@
 
 import org.hps.conditions.api.ConditionsObject;
 import org.hps.conditions.api.ConditionsObjectCollection;
+import org.hps.conditions.api.TableMetaData;
 import org.hps.conditions.database.DatabaseConditionsManager;
-import org.hps.conditions.database.TableMetaData;
 
 /**
  * This is a table model for a collection of conditions objects.
@@ -53,11 +53,8 @@
         this.collection = collection;
         this.rowCount = this.collection.size();
 
-        final String tableName = collection.getConditionsRecord().getTableName();
-        final TableMetaData tableInfo = manager.findTableMetaData(tableName);
-
         // Set column names and count from table meta data.
-        this.setupColumns(tableInfo);
+        this.setupColumns(collection.getTableMetaData());
     }
 
     /**
@@ -134,7 +131,7 @@
      */
     private void setupColumns(final TableMetaData tableInfo) {
 
-        final int fieldNameCount = tableInfo.getFieldNames().length;
+        final int fieldNameCount = tableInfo.getFieldNames().size();
         this.columnCount = fieldNameCount + 1;
 
         this.columnTypes = new Class<?>[this.columnCount];
@@ -143,10 +140,10 @@
         this.columnNames[0] = "id";
         this.columnTypes[0] = int.class;
 
-        for (int i = 0; i < fieldNameCount; i++) {
-            final String fieldName = tableInfo.getFieldNames()[i];
-            this.columnNames[i + 1] = fieldName;
-            this.columnTypes[i + 1] = tableInfo.getFieldType(fieldName);
+        int columnNumber = 1;
+        for (String fieldName : tableInfo.getFieldNames()) {
+            this.columnNames[columnNumber + 1] = fieldName;
+            this.columnTypes[columnNumber + 1] = tableInfo.getFieldType(fieldName);
         }
     }
 }

Modified: java/trunk/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalLedSequenceMonitor.java
 =============================================================================
--- java/trunk/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalLedSequenceMonitor.java	(original)
+++ java/trunk/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalLedSequenceMonitor.java	Wed Jul  8 14:47:40 2015
@@ -1,68 +1,49 @@
 package org.hps.monitoring.ecal.plots;
 
 
+import hep.aida.IEvaluator;
+import hep.aida.IFitResult;
+import hep.aida.IFitter;
+import hep.aida.IFunction;
+import hep.aida.IFunctionFactory;
 import hep.aida.IHistogram1D;
 import hep.aida.IHistogram2D;
+import hep.aida.IPlotter;
+import hep.aida.IPlotterFactory;
+import hep.aida.IPlotterStyle;
 import hep.aida.IProfile1D;
 import hep.aida.ITuple;
-import hep.aida.IFunction;
-import hep.aida.IPlotter;
-import hep.aida.IFitter;
-import hep.aida.IFitResult;
-import hep.aida.IFunctionFactory;
-import hep.aida.IPlotterStyle;
-import hep.aida.IPlotterFactory;
-import hep.aida.ICloud1D;
-import hep.aida.ICloud2D;
-import hep.aida.IEvaluator;
-import hep.aida.ITreeFactory;
-import hep.aida.ITupleFactory;
-
-import javax.swing.JFrame;
-import javax.swing.JButton;
-import javax.swing.JPanel;
-import javax.swing.JLabel;
-import javax.swing.JDialog;
-import javax.swing.JOptionPane;
-import javax.swing.JTextArea;
-import javax.swing.UIManager;
-import javax.swing.Icon;
-import javax.swing.WindowConstants;
-
-import java.awt.Dimension;
-import java.awt.FlowLayout;
-import java.awt.EventQueue;
+
+import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.awt.event.ActionEvent;
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeEvent;
-import java.lang.InterruptedException;
-import java.util.Arrays;
-import java.io.Console;
 import java.io.File;
 import java.sql.SQLException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
 import org.hps.conditions.api.ConditionsObjectException;
 import org.hps.conditions.api.ConditionsRecord;
+import org.hps.conditions.api.DatabaseObjectException;
+import org.hps.conditions.api.TableMetaData;
 import org.hps.conditions.database.DatabaseConditionsManager;
-import org.hps.conditions.database.TableMetaData;
 import org.hps.conditions.ecal.EcalChannel;
-import org.hps.conditions.ecal.EcalCalibration.EcalCalibrationCollection;
 import org.hps.conditions.ecal.EcalChannel.EcalChannelCollection;
-import org.hps.conditions.ecal.EcalChannel.GeometryId;
+import org.hps.conditions.ecal.EcalChannelConstants;
+import org.hps.conditions.ecal.EcalConditions;
 import org.hps.conditions.ecal.EcalLed;
 import org.hps.conditions.ecal.EcalLed.EcalLedCollection;
 import org.hps.conditions.ecal.EcalLedCalibration;
 import org.hps.conditions.ecal.EcalLedCalibration.EcalLedCalibrationCollection;
-import org.hps.conditions.ecal.EcalCalibration;
-import org.hps.conditions.ecal.EcalConditions;
-import org.hps.conditions.ecal.EcalChannelConstants;
 import org.hps.recon.ecal.EcalUtils;
-import org.hps.monitoring.ecal.plots.EcalMonitoringUtilities;
 import org.lcsim.event.CalorimeterHit;
 import org.lcsim.event.EventHeader;
 import org.lcsim.geometry.Detector;
@@ -615,7 +596,11 @@
         }
         if (m_ret==1){
             System.out.println("OK, upload to DB");
-            uploadToDB();
+            try {
+            	uploadToDB();
+            } catch (SQLException | DatabaseObjectException | ConditionsObjectException error) {
+            	throw new RuntimeException("Error uploading to the database.", error);
+            }
             if (isMonitoringApp){
                 System.out.println("Save an Elog too");
                 uploadToElog();
@@ -658,7 +643,7 @@
 
     }
 
-    private void uploadToDB() {
+    private void uploadToDB() throws DatabaseObjectException, ConditionsObjectException, SQLException {
         int x,y,id;
         double mean,rms;
         System.out.println(String.format("Uploading new led data to the database, runMin=%d, runMax=%d, tag=%s ....",
@@ -682,22 +667,16 @@
         int collectionId = -1;
 
         try {
-            collectionId = conditionsManager.addCollection(dbTableName, "EcalLedSequenceMonitor generated by " + System.getProperty("user.name"), null);
+            collectionId = conditionsManager.getCollectionId(led_calibrations, "loaded by EcalLedSequenceMonitor");
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
-        try {
-            led_calibrations.setCollectionId(collectionId);
-            System.err.println("CollectionID:  "+collectionId);
-            led_calibrations.insert();
-            ConditionsRecord conditionsRecord = new ConditionsRecord(
-                    led_calibrations.getCollectionId(), runNumber, runNumberMax, dbTableName, dbTableName, 
-                    "Generated by LedAnalysis from Run #"+runNumber, dbTag);
-            conditionsRecord.insert();
-
-        } catch (ConditionsObjectException | SQLException e) {
-            throw new RuntimeException(e);
-        }
+        System.err.println("CollectionID:  "+collectionId);
+        led_calibrations.insert();
+        ConditionsRecord conditionsRecord = new ConditionsRecord(
+        		led_calibrations.getCollectionId(), runNumber, runNumberMax, dbTableName, dbTableName, 
+        		"Generated by LedAnalysis from Run #"+runNumber, dbTag);
+        conditionsRecord.insert();
 
         System.out.println("Upload to DB done");
     }