void CLSSIS3820ScalerDarkCurrentMeasurementAction::startImplementation()
{
	// Must have a valid, connected scaler.

	CLSSIS3820Scaler *scaler = CLSBeamline::clsBeamline()->scaler();

	if (! (scaler && scaler->isConnected()) ) {
		QString message = QString("There was an error measuring scaler dark current. The scaler is invalid or not connected.");
		AMErrorMon::alert(this, CLSSIS3820SCALERDARKCURRENTMEASUREMENTACTION_INVALID_SCALER, message);
		setFailed(message);
	}

	// Must have a valid dwell time.

	double secondsDwell = scalerDarkCurrentMeasurementActionInfo()->dwellTime();

	if (!validDwellTime(secondsDwell)) {
		QString message = QString("There was an error measuring scaler dark current. The dwell time provided (%1 s) is invalid.").arg(secondsDwell);
		AMErrorMon::alert(this, CLSSIS3820SCALERDARKCURRENTMEASUREMENTACTION_INVALID_DWELL_TIME, message);
		setFailed(message);
	}

	// Update pre-measurement settings, to be restored once measurement is complete.

	measurementInitialization();

	// Create measurement action.

	AMAction3 *measurementAction = createMeasurementAction(secondsDwell);

	// Make connections and start action.

	if (measurementAction) {

		startedMapper_->setMapping(measurementAction, measurementAction);
		failedMapper_->setMapping(measurementAction, measurementAction);
		succeededMapper_->setMapping(measurementAction, measurementAction);

		connect( measurementAction, SIGNAL(started()), startedMapper_, SLOT(map()) );
		connect( measurementAction, SIGNAL(failed()), failedMapper_, SLOT(map()) );
		connect( measurementAction, SIGNAL(succeeded()), succeededMapper_, SLOT(map()) );

		measurementAction->start();

	} else {

		QString message = QString("There was an error measuring scaler dark current. An invalid measurement action was generated.");
		AMErrorMon::alert(this, CLSSIS3820SCALERDARKCURRENTMEASUREMENTACTION_INVALID_ACTION, message);
		setFailed(message);
	}
}
CLSSIS3820ScalerDarkCurrentMeasurementAction::CLSSIS3820ScalerDarkCurrentMeasurementAction(CLSSIS3820ScalerDarkCurrentMeasurementActionInfo *info, QObject *parent) :
    AMListAction3(info, AMListAction3::Sequential, parent)
{
	CLSSIS3820Scaler *scaler = CLSBeamline::clsBeamline()->scaler();
	double secondsDwell = scalerDarkCurrentMeasurementActionInfo()->dwellTime();

	connect( this, SIGNAL(failed()), this, SLOT(onActionFailed()) );

	if (scaler && scaler->isConnected() && secondsDwell > 0) {

		// pre-measurement settings.
		double oldDwell = scaler->dwellTime();

		// first turn off beam.
//		addSubAction(AMBeamline::bl()->createTurnOffBeamActions());

		// set the scaler's dwell time to new time.
		addSubAction(scaler->createDwellTimeAction3(secondsDwell));

		// initiate a scaler measurement and wait until it is complete.
		addSubAction(scaler->createStartAction3(true));
		addSubAction(scaler->createWaitForDwellFinishedAction(secondsDwell + 5.0));

		// notify attached and able scaler channel detectors that the latest measurement was a dark current measurement.
		AMListAction3 *notifyChannelDetectors = new AMListAction3(new AMListActionInfo3("Set last measurement as dark current measurement", "Set last measurement as dark current measurement"));

		for (int i = 0; i < scaler->channels().count(); i++) {
			CLSSIS3820ScalerChannel *channel = scaler->channelAt(i);

			if (channel && channel->isEnabled() && channel->detector() && channel->detector()->canDoDarkCurrentCorrection()) {
				notifyChannelDetectors->addSubAction(channel->detector()->createSetLastMeasurementAsDarkCurrentAction());
			}
		}

		addSubAction(notifyChannelDetectors);

		// reset settings to pre-measurement conditions.
		addSubAction(scaler->createDwellTimeAction3(oldDwell));

	} else {
		AMErrorMon::alert(this, CLSSIS3820SCALERDARKCURRENTMEASUREMENTACTION_SCALER_NOT_VALID, "Failed to complete dark current measurement--scaler not valid.");
		setFailed();
	}

}