public class ATTObject implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "ATT";
	
	private String tag = null;
	
	private String device = null;
	
	private double timestamp = Double.NaN;
	
	private double heading = Double.NaN;
	
	private double pitch = Double.NaN;
	
	private double yaw = Double.NaN;
	
	private double roll = Double.NaN;
	
	private double dip = Double.NaN;
	
	private double mag_len = Double.NaN;
	
	private double mag_x = Double.NaN;
	
	private double mag_y = Double.NaN;
	
	private double mag_z = Double.NaN;
	
	private double acc_len = Double.NaN;
	
	private double acc_x = Double.NaN;
	
	private double acc_y = Double.NaN;
	
	private double acc_z = Double.NaN;
	
	private double gyro_x = Double.NaN;
	
	private double gyro_y = Double.NaN;
	
	private double depth = Double.NaN;
	
	private double temperature = Double.NaN;
	
	private String magState = null;
	
	private String pitchState = null;
	
	private String yawState = null;
	
	private String rollState = null;
	
	/**
	 * Type tag associated with this GPS sentence; from an NMEA device this is just the NMEA sentence type.
	 *
	 * @return the tag
	 */
	public String getTag() {
		return this.tag;
	}
	
	/**
	 * Type tag associated with this GPS sentence; from an NMEA device this is just the NMEA sentence type.
	 *
	 * @param tag the tag to set
	 */
	public void setTag(final String tag) {
		this.tag = tag;
	}
	
	/**
	 * Name of originating device
	 *
	 * @return the device
	 */
	public String getDevice() {
		return this.device;
	}
	
	/**
	 * Name of originating device
	 *
	 * @param device the device to set
	 */
	public void setDevice(final String device) {
		this.device = device;
	}
	
	/**
	 * Seconds since the Unix epoch, UTC. May have a fractional part of up to .001sec precision.
	 *
	 * @return the timestamp
	 */
	public double getTimestamp() {
		return this.timestamp;
	}
	
	/**
	 * Seconds since the Unix epoch, UTC. May have a fractional part of up to .001sec precision.
	 *
	 * @param timestamp the timestamp to set
	 */
	public void setTimestamp(final double timestamp) {
		this.timestamp = timestamp;
	}
	
	/**
	 * Heading, degrees from true north.
	 *
	 * @return the heading
	 */
	public double getHeading() {
		return this.heading;
	}
	
	/**
	 * Heading, degrees from true north.
	 *
	 * @param heading the heading to set
	 */
	public void setHeading(final double heading) {
		this.heading = heading;
	}
	
	/**
	 * Pitch in degrees.
	 *
	 * @return the pitch
	 */
	public double getPitch() {
		return this.pitch;
	}
	
	/**
	 * Pitch in degrees.
	 *
	 * @param pitch the pitch to set
	 */
	public void setPitch(final double pitch) {
		this.pitch = pitch;
	}
	
	/**
	 * Yaw in degrees
	 *
	 * @return the yaw
	 */
	public double getYaw() {
		return this.yaw;
	}
	
	/**
	 * Yaw in degrees
	 *
	 * @param yaw the yaw to set
	 */
	public void setYaw(final double yaw) {
		this.yaw = yaw;
	}
	
	/**
	 * Roll in degrees.
	 *
	 * @return the roll
	 */
	public double getRoll() {
		return this.roll;
	}
	
	/**
	 * Roll in degrees.
	 *
	 * @param roll the roll to set
	 */
	public void setRoll(final double roll) {
		this.roll = roll;
	}
	
	/**
	 * Roll in degrees.
	 *
	 * @return the dip
	 */
	public double getDip() {
		return this.dip;
	}
	
	/**
	 * Roll in degrees.
	 *
	 * @param dip the dip to set
	 */
	public void setDip(final double dip) {
		this.dip = dip;
	}
	
	/**
	 * Scalar magnetic field strength.
	 *
	 * @return the mag_len
	 */
	public double getMag_len() {
		return this.mag_len;
	}
	
	/**
	 * Scalar magnetic field strength.
	 *
	 * @param mag_len the mag_len to set
	 */
	public void setMag_len(final double mag_len) {
		this.mag_len = mag_len;
	}
	
	/**
	 * X component of magnetic field strength.
	 *
	 * @return the mag_x
	 */
	public double getMag_x() {
		return this.mag_x;
	}
	
	/**
	 * X component of magnetic field strength.
	 *
	 * @param mag_x the mag_x to set
	 */
	public void setMag_x(final double mag_x) {
		this.mag_x = mag_x;
	}
	
	/**
	 * Y component of magnetic field strength.
	 *
	 * @return the mag_y
	 */
	public double getMag_y() {
		return this.mag_y;
	}
	
	/**
	 * Y component of magnetic field strength.
	 *
	 * @param mag_y the mag_y to set
	 */
	public void setMag_y(final double mag_y) {
		this.mag_y = mag_y;
	}
	
	/**
	 * Z component of magnetic field strength.
	 *
	 * @return the mag_z
	 */
	public double getMag_z() {
		return this.mag_z;
	}
	
	/**
	 * Z component of magnetic field strength.
	 *
	 * @param mag_z the mag_z to set
	 */
	public void setMag_z(final double mag_z) {
		this.mag_z = mag_z;
	}
	
	/**
	 * Scalar acceleration.
	 *
	 * @return the acc_len
	 */
	public double getAcc_len() {
		return this.acc_len;
	}
	
	/**
	 * Scalar acceleration.
	 *
	 * @param acc_len the acc_len to set
	 */
	public void setAcc_len(final double acc_len) {
		this.acc_len = acc_len;
	}
	
	/**
	 * X component of acceleration.
	 *
	 * @return the acc_x
	 */
	public double getAcc_x() {
		return this.acc_x;
	}
	
	/**
	 * X component of acceleration.
	 *
	 * @param acc_x the acc_x to set
	 */
	public void setAcc_x(final double acc_x) {
		this.acc_x = acc_x;
	}
	
	/**
	 * Y component of acceleration.
	 *
	 * @return the acc_y
	 */
	public double getAcc_y() {
		return this.acc_y;
	}
	
	/**
	 * Y component of acceleration.
	 *
	 * @param acc_y the acc_y to set
	 */
	public void setAcc_y(final double acc_y) {
		this.acc_y = acc_y;
	}
	
	/**
	 * Z component of acceleration.
	 *
	 * @return the acc_z
	 */
	public double getAcc_z() {
		return this.acc_z;
	}
	
	/**
	 * Z component of acceleration.
	 *
	 * @param acc_z the acc_z to set
	 */
	public void setAcc_z(final double acc_z) {
		this.acc_z = acc_z;
	}
	
	/**
	 * X component of acceleration.
	 *
	 * @return the gyro_x
	 */
	public double getGyro_x() {
		return this.gyro_x;
	}
	
	/**
	 * X component of acceleration.
	 *
	 * @param gyro_x the gyro_x to set
	 */
	public void setGyro_x(final double gyro_x) {
		this.gyro_x = gyro_x;
	}
	
	/**
	 * Y component of acceleration.
	 *
	 * @return the gyro_y
	 */
	public double getGyro_y() {
		return this.gyro_y;
	}
	
	/**
	 * Y component of acceleration.
	 *
	 * @param gyro_y the gyro_y to set
	 */
	public void setGyro_y(final double gyro_y) {
		this.gyro_y = gyro_y;
	}
	
	/**
	 * Water depth in meters.
	 *
	 * @return the depth
	 */
	public double getDepth() {
		return this.depth;
	}
	
	/**
	 * Water depth in meters.
	 *
	 * @param depth the depth to set
	 */
	public void setDepth(final double depth) {
		this.depth = depth;
	}
	
	/**
	 * Temperature at sensor, degrees centigrade.
	 *
	 * @return the temperature
	 */
	public double getTemperature() {
		return this.temperature;
	}
	
	/**
	 * Temperature at sensor, degrees centigrade.
	 *
	 * @param temperature the temperature to set
	 */
	public void setTemperature(final double temperature) {
		this.temperature = temperature;
	}
	
	/**
	 * Magnetometer status.
	 *
	 * @return the magState
	 */
	public String getMagState() {
		return this.magState;
	}
	
	/**
	 * Magnetometer status.
	 *
	 * @param magState the magState to set
	 */
	public void setMagState(final String magState) {
		this.magState = magState;
	}
	
	/**
	 * Pitch sensor status.
	 *
	 * @return the pitchState
	 */
	public String getPitchState() {
		return this.pitchState;
	}
	
	/**
	 * Pitch sensor status.
	 *
	 * @param pitchState the pitchState to set
	 */
	public void setPitchState(final String pitchState) {
		this.pitchState = pitchState;
	}
	
	/**
	 * Yaw sensor status.
	 *
	 * @return the yawState
	 */
	public String getYawState() {
		return this.yawState;
	}
	
	/**
	 * Yaw sensor status.
	 *
	 * @param yawState the yawState to set
	 */
	public void setYawState(final String yawState) {
		this.yawState = yawState;
	}
	
	/**
	 * Roll sensor status.
	 *
	 * @return the rollState
	 */
	public String getRollState() {
		return this.rollState;
	}
	
	/**
	 * Roll sensor status.
	 *
	 * @param rollState the rollState to set
	 */
	public void setRollState(final String rollState) {
		this.rollState = rollState;
	}
	
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		sb.append("ATTObject{tag=");
		sb.append(this.tag);
		sb.append(", device=");
		sb.append(this.device);
		sb.append(", timestamp=");
		sb.append(this.timestamp);
		sb.append(", heading=");
		sb.append(this.heading);
		sb.append(", mag_st=");
		sb.append(this.magState);
		sb.append(", pitch=");
		sb.append(this.pitch);
		sb.append(", pitch_st=");
		sb.append(this.pitchState);
		sb.append(", yaw=");
		sb.append(this.yawState);
		sb.append(", roll=");
		sb.append(this.roll);
		sb.append(", roll_st=");
		sb.append(this.rollState);
		sb.append(", dip=");
		sb.append(this.dip);
		sb.append(", mag_len=");
		sb.append(this.mag_len);
		sb.append(", mag_x=");
		sb.append(this.mag_x);
		sb.append(", mag_y=");
		sb.append(this.mag_y);
		sb.append(", mag_z=");
		sb.append(this.mag_z);
		sb.append(", acc_len=");
		sb.append(this.acc_len);
		sb.append(", acc_x=");
		sb.append(this.acc_x);
		sb.append(", acc_y=");
		sb.append(this.acc_y);
		sb.append(", acc_z=");
		sb.append(this.acc_z);
		sb.append(", gyro_x=");
		sb.append(this.gyro_x);
		sb.append(", gyro_y=");
		sb.append(this.gyro_y);
		sb.append(", depth=");
		sb.append(this.depth);
		sb.append(", temperature=");
		sb.append(this.temperature);
		sb.append("}");
		return sb.toString();
	}
} public class DeviceObject implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "DEVICE";
	
	private String path;
	
	private double activated;
	
	private String driver;
	
	private int bps;
	
	private EParity parity;
	
	private int stopbit;
	
	private boolean nativeMode;
	
	private double cycle;
	
	private double mincycle;
	
	/**
	 * Name the device for which the control bits are being reported
	 *
	 * @return the path
	 */
	public String getPath() {
		return this.path;
	}
	
	/**
	 * Name the device for which the control bits are being reported
	 *
	 * @param path the path to set
	 */
	public void setPath(final String path) {
		this.path = path;
	}
	
	/**
	 * Time the device was activated, or 0 if it is being closed.
	 *
	 * @return the activated
	 */
	public double getActivated() {
		return this.activated;
	}
	
	/**
	 * Time the device was activated, or 0 if it is being closed.
	 *
	 * @param activated the activated to set
	 */
	public void setActivated(final double activated) {
		this.activated = activated;
	}
	
	/**
	 * GPSD's name for the device driver type. Won't be reported before gpsd has seen identifiable packets from the device.
	 *
	 * @return the driver
	 */
	public String getDriver() {
		return this.driver;
	}
	
	/**
	 * GPSD's name for the device driver type. Won't be reported before gpsd has seen identifiable packets from the device.
	 *
	 * @param driver the driver to set
	 */
	public void setDriver(final String driver) {
		this.driver = driver;
	}
	
	/**
	 * Device speed in bits per second.
	 *
	 * @return the bps
	 */
	public int getBps() {
		return this.bps;
	}
	
	/**
	 * Device speed in bits per second.
	 *
	 * @param bps the bps to set
	 */
	public void setBps(final int bps) {
		this.bps = bps;
	}
	
	/**
	 * Device parity
	 *
	 * @return the parity
	 */
	public EParity getParity() {
		return this.parity;
	}
	
	/**
	 * Device parity
	 *
	 * @param parity the parity to set
	 */
	public void setParity(final EParity parity) {
		this.parity = parity;
	}
	
	/**
	 * Device Stopbits
	 *
	 * @return the stopbit
	 */
	public int getStopbit() {
		return this.stopbit;
	}
	
	/**
	 * Device Stopbits
	 *
	 * @param stopbit the stopbit to set
	 */
	public void setStopbit(final int stopbit) {
		this.stopbit = stopbit;
	}
	
	/**
	 * false means NMEA mode and true means alternate mode (binary if it has one, for SiRF and Evermore chipsets in particular).
	 *
	 * @return the nativeMode
	 */
	public boolean isNativeMode() {
		return this.nativeMode;
	}
	
	/**
	 * false means NMEA mode and true means alternate mode (binary if it has one, for SiRF and Evermore chipsets in particular).
	 *
	 * @param nativeMode the nativeMode to set
	 */
	public void setNativeMode(final boolean nativeMode) {
		this.nativeMode = nativeMode;
	}
	
	/**
	 * Device cycle time in seconds.
	 *
	 * @return the cycle
	 */
	public double getCycle() {
		return this.cycle;
	}
	
	/**
	 * Device cycle time in seconds.
	 *
	 * @param cycle the cycle to set
	 */
	public void setCycle(final double cycle) {
		this.cycle = cycle;
	}
	
	/**
	 * Device minimum cycle time in seconds.
	 *
	 * @return the mincycle
	 */
	public double getMincycle() {
		return this.mincycle;
	}
	
	/**
	 * Device minimum cycle time in seconds.
	 *
	 * @param mincycle the mincycle to set
	 */
	public void setMincycle(final double mincycle) {
		this.mincycle = mincycle;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		long temp;
		temp = Double.doubleToLongBits(this.activated);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		result = (prime * result) + this.bps;
		temp = Double.doubleToLongBits(this.cycle);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		result = (prime * result) + ((this.driver == null) ? 0 : this.driver.hashCode());
		temp = Double.doubleToLongBits(this.mincycle);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		result = (prime * result) + (this.nativeMode ? 1231 : 1237);
		result = (prime * result) + ((this.parity == null) ? 0 : this.parity.hashCode());
		result = (prime * result) + ((this.path == null) ? 0 : this.path.hashCode());
		result = (prime * result) + this.stopbit;
		return result;
	}
	
	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (this.getClass() != obj.getClass()) {
			return false;
		}
		final DeviceObject other = (DeviceObject) obj;
		if (Double.doubleToLongBits(this.activated) != Double.doubleToLongBits(other.activated)) {
			return false;
		}
		if (this.bps != other.bps) {
			return false;
		}
		if (Double.doubleToLongBits(this.cycle) != Double.doubleToLongBits(other.cycle)) {
			return false;
		}
		if (this.driver == null) {
			if (other.driver != null) {
				return false;
			}
		} else if (!this.driver.equals(other.driver)) {
			return false;
		}
		if (Double.doubleToLongBits(this.mincycle) != Double.doubleToLongBits(other.mincycle)) {
			return false;
		}
		if (this.nativeMode != other.nativeMode) {
			return false;
		}
		if (this.parity != other.parity) {
			return false;
		}
		if (this.path == null) {
			if (other.path != null) {
				return false;
			}
		} else if (!this.path.equals(other.path)) {
			return false;
		}
		if (this.stopbit != other.stopbit) {
			return false;
		}
		return true;
	}
	
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		sb.append("DeviceObject{path=");
		sb.append(this.path);
		sb.append(", driver=");
		sb.append(this.driver);
		sb.append(", activated=");
		sb.append((long) this.activated);
		sb.append(", bps=");
		sb.append(this.bps);
		sb.append(", parity=");
		sb.append(this.parity);
		sb.append(", stopbit=");
		sb.append(this.stopbit);
		sb.append(", nativeMode=");
		sb.append(this.nativeMode);
		sb.append(", cycle=");
		sb.append(this.cycle);
		sb.append(", minCycle=");
		sb.append(this.mincycle);
		sb.append("}");
		return sb.toString();
	}
	
} public class DevicesObject implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "DEVICES";
	
	private List<DeviceObject> devices;
	
	/**
	 * list of devices
	 *
	 * @return the devices
	 */
	public List<DeviceObject> getDevices() {
		return this.devices;
	}
	
	/**
	 * list of devices
	 *
	 * @param devices the devices to set
	 */
	public void setDevices(final List<DeviceObject> devices) {
		this.devices = devices;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = (prime * result) + ((this.devices == null) ? 0 : this.devices.hashCode());
		return result;
	}
	
	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (this.getClass() != obj.getClass()) {
			return false;
		}
		final DevicesObject other = (DevicesObject) obj;
		if (this.devices == null) {
			if (other.devices != null) {
				return false;
			}
		} else if (!this.devices.equals(other.devices)) {
			return false;
		}
		return true;
	}
	
	@Override
	public String toString() {
		return "DevicesObject{devices=" + ((this.devices == null) ? 0 : this.devices.size()) + "}";
	}
	
} public enum ENMEAMode {
	
	/**
	 * no mode value yet seen
	 */
	NotSeen,
	/**
	 * No fix available
	 */
	NoFix,
	/**
	 * two dimensional fix
	 */
	TwoDimensional,
	/**
	 * three dimensional fix
	 */
	ThreeDimensional;
	
	/**
	 * @param mode - mode integer
	 * @return {@link ENMEAMode}
	 */
	public static ENMEAMode fromInt(final int mode) {
		switch (mode) {
		case 0:
			return NotSeen;
		case 1:
			return NoFix;
		case 2:
			return TwoDimensional;
		case 3:
			return ThreeDimensional;
		default:
			break;
		}
		return NotSeen;
	}
} public enum EParity {
	
	/**
	 *
	 */
	NO,
	/**
	 *
	 */
	ODD,
	/**
	 *
	 */
	EVEN;
	
	/**
	 * @param parity the parity string
	 * @return {@link EParity}
	 */
	public static EParity fromString(final String parity) {
		if (parity == null) {
			return NO;
		}
		if (parity.equals("N")) {
			return NO;
		}
		if (parity.equals("O")) {
			return ODD;
		}
		if (parity.equals("E")) {
			return EVEN;
		}
		return NO;
	}
} public class GSTObject implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "GST";
	
	private String tag = null;
	
	private String device = null;
	
	private double timestamp = Double.NaN;
	
	private double rms = Double.NaN;
	
	private double major = Double.NaN;
	
	private double minor = Double.NaN;
	
	private double orient = Double.NaN;
	
	private double lat = Double.NaN;
	
	private double lon = Double.NaN;
	
	private double alt = Double.NaN;
	
	/**
	 * Type tag associated with this GPS sentence; from an NMEA device this is just the NMEA sentence type.
	 *
	 * @return the tag
	 */
	public String getTag() {
		return this.tag;
	}
	
	/**
	 * Type tag associated with this GPS sentence; from an NMEA device this is just the NMEA sentence type.
	 *
	 * @param tag the tag to set
	 */
	public void setTag(final String tag) {
		this.tag = tag;
	}
	
	/**
	 * Name of originating device
	 *
	 * @return the device
	 */
	public String getDevice() {
		return this.device;
	}
	
	/**
	 * Name of originating device
	 *
	 * @param device the device to set
	 */
	public void setDevice(final String device) {
		this.device = device;
	}
	
	/**
	 * Seconds since the Unix epoch, UTC. May have a fractional part of up to .001sec precision.
	 *
	 * @return the timestamp
	 */
	public double getTimestamp() {
		return this.timestamp;
	}
	
	/**
	 * Seconds since the Unix epoch, UTC. May have a fractional part of up to .001sec precision.
	 *
	 * @param timestamp the timestamp to set
	 */
	public void setTimestamp(final double timestamp) {
		this.timestamp = timestamp;
	}
	
	/**
	 * Value of the standard deviation of the range inputs to the navigation process (range inputs include pseudoranges and DGPS
	 * corrections).
	 *
	 * @return the rms
	 */
	public double getRms() {
		return this.rms;
	}
	
	/**
	 * Value of the standard deviation of the range inputs to the navigation process (range inputs include pseudoranges and DGPS
	 * corrections).
	 *
	 * @param rms the rms to set
	 */
	public void setRms(final double rms) {
		this.rms = rms;
	}
	
	/**
	 * Standard deviation of semi-major axis of error ellipse, in meters.
	 *
	 * @return the major
	 */
	public double getMajor() {
		return this.major;
	}
	
	/**
	 * Standard deviation of semi-major axis of error ellipse, in meters.
	 *
	 * @param major the major to set
	 */
	public void setMajor(final double major) {
		this.major = major;
	}
	
	/**
	 * Standard deviation of semi-minor axis of error ellipse, in meters.
	 *
	 * @return the minor
	 */
	public double getMinor() {
		return this.minor;
	}
	
	/**
	 * Standard deviation of semi-minor axis of error ellipse, in meters.
	 *
	 * @param minor the minor to set
	 */
	public void setMinor(final double minor) {
		this.minor = minor;
	}
	
	/**
	 * Orientation of semi-major axis of error ellipse, in degrees from true north.
	 *
	 * @return the orient
	 */
	public double getOrient() {
		return this.orient;
	}
	
	/**
	 * Orientation of semi-major axis of error ellipse, in degrees from true north.
	 *
	 * @param orient the orient to set
	 */
	public void setOrient(final double orient) {
		this.orient = orient;
	}
	
	/**
	 * Standard deviation of latitude error, in meters.
	 *
	 * @return the lat
	 */
	public double getLat() {
		return this.lat;
	}
	
	/**
	 * Standard deviation of latitude error, in meters.
	 *
	 * @param lat the lat to set
	 */
	public void setLat(final double lat) {
		this.lat = lat;
	}
	
	/**
	 * Standard deviation of longitude error, in meters.
	 *
	 * @return the lon
	 */
	public double getLon() {
		return this.lon;
	}
	
	/**
	 * Standard deviation of longitude error, in meters.
	 *
	 * @param lon the lon to set
	 */
	public void setLon(final double lon) {
		this.lon = lon;
	}
	
	/**
	 * Standard deviation of altitude error, in meters.
	 *
	 * @return the alt
	 */
	public double getAlt() {
		return this.alt;
	}
	
	/**
	 * Standard deviation of altitude error, in meters.
	 *
	 * @param alt the alt to set
	 */
	public void setAlt(final double alt) {
		this.alt = alt;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		long temp;
		temp = Double.doubleToLongBits(this.alt);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		result = (prime * result) + ((this.device == null) ? 0 : this.device.hashCode());
		temp = Double.doubleToLongBits(this.lat);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.lon);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.major);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.minor);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.orient);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.rms);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		result = (prime * result) + ((this.tag == null) ? 0 : this.tag.hashCode());
		temp = Double.doubleToLongBits(this.timestamp);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		return result;
	}
	
	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (this.getClass() != obj.getClass()) {
			return false;
		}
		final GSTObject other = (GSTObject) obj;
		if (Double.doubleToLongBits(this.alt) != Double.doubleToLongBits(other.alt)) {
			return false;
		}
		if (this.device == null) {
			if (other.device != null) {
				return false;
			}
		} else if (!this.device.equals(other.device)) {
			return false;
		}
		if (Double.doubleToLongBits(this.lat) != Double.doubleToLongBits(other.lat)) {
			return false;
		}
		if (Double.doubleToLongBits(this.lon) != Double.doubleToLongBits(other.lon)) {
			return false;
		}
		if (Double.doubleToLongBits(this.major) != Double.doubleToLongBits(other.major)) {
			return false;
		}
		if (Double.doubleToLongBits(this.minor) != Double.doubleToLongBits(other.minor)) {
			return false;
		}
		if (Double.doubleToLongBits(this.orient) != Double.doubleToLongBits(other.orient)) {
			return false;
		}
		if (Double.doubleToLongBits(this.rms) != Double.doubleToLongBits(other.rms)) {
			return false;
		}
		if (this.tag == null) {
			if (other.tag != null) {
				return false;
			}
		} else if (!this.tag.equals(other.tag)) {
			return false;
		}
		if (Double.doubleToLongBits(this.timestamp) != Double.doubleToLongBits(other.timestamp)) {
			return false;
		}
		return true;
	}
	
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		sb.append("GSTObject{tag=");
		sb.append(this.tag);
		sb.append(", device=");
		sb.append(this.device);
		sb.append(", timestamp=");
		sb.append(this.timestamp);
		sb.append(", rms=");
		sb.append(this.rms);
		sb.append(", major=");
		sb.append(this.major);
		sb.append(", minor=");
		sb.append(this.minor);
		sb.append(", orient=");
		sb.append(this.orient);
		sb.append(", lat=");
		sb.append(this.lat);
		sb.append(", lon=");
		sb.append(this.lon);
		sb.append(", alt=");
		sb.append(this.alt);
		sb.append("}");
		return sb.toString();
	}
} public interface IGPSObject {
	
	// this is only a marker interface
	
} public class ParseException extends Exception {
	
	private static final long serialVersionUID = 7747422116792199432L;
	
	/**
	 *
	 */
	public ParseException() {
		super();
	}
	
	/**
	 * @param message the message
	 */
	public ParseException(final String message) {
		super(message);
	}
	
	/**
	 * @param message the message
	 * @param cause   the cause
	 */
	public ParseException(final String message, final Throwable cause) {
		super(message, cause);
	}
	
	/**
	 * @param cause the cause
	 */
	public ParseException(final Throwable cause) {
		super(cause);
	}
	
} public class PollObject implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "POLL";
	
	private double timestamp;
	
	private int active;
	
	private List<TPVObject> fixes;
	
	private List<SKYObject> skyviews;
	
	private List<GSTObject> gst;
	
	/**
	 * Seconds since the Unix epoch, UTC. May have a fractional part of up to .001sec precision.
	 *
	 * @return the timestamp
	 */
	public double getTimestamp() {
		return this.timestamp;
	}
	
	/**
	 * Seconds since the Unix epoch, UTC. May have a fractional part of up to .001sec precision.
	 *
	 * @param timestamp the timestamp to set
	 */
	public void setTimestamp(final double timestamp) {
		this.timestamp = timestamp;
	}
	
	/**
	 * Count of active devices.
	 *
	 * @return the active
	 */
	public int getActive() {
		return this.active;
	}
	
	/**
	 * Count of active devices.
	 *
	 * @param active the active to set
	 */
	public void setActive(final int active) {
		this.active = active;
	}
	
	/**
	 * list of TPV objects
	 *
	 * @return the fixes
	 */
	public List<TPVObject> getFixes() {
		return this.fixes;
	}
	
	/**
	 * list of TPV objects
	 *
	 * @param fixes the fixes to set
	 */
	public void setFixes(final List<TPVObject> fixes) {
		this.fixes = fixes;
	}
	
	/**
	 * list of SKY objects
	 *
	 * @return the skyviews
	 */
	public List<SKYObject> getSkyviews() {
		return this.skyviews;
	}
	
	/**
	 * list of SKY objects
	 *
	 * @param skyviews the skyviews to set
	 */
	public void setSkyviews(final List<SKYObject> skyviews) {
		this.skyviews = skyviews;
	}
	
	/**
	 * @return the gst
	 */
	public List<GSTObject> getGst() {
		return this.gst;
	}
	
	/**
	 * @param gst the gst to set
	 */
	public void setGst(final List<GSTObject> gst) {
		this.gst = gst;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = (prime * result) + this.active;
		result = (prime * result) + ((this.fixes == null) ? 0 : this.fixes.hashCode());
		result = (prime * result) + ((this.skyviews == null) ? 0 : this.skyviews.hashCode());
		result = (prime * result) + ((this.gst == null) ? 0 : this.gst.hashCode());
		long temp;
		temp = Double.doubleToLongBits(this.timestamp);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		return result;
	}
	
	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (this.getClass() != obj.getClass()) {
			return false;
		}
		final PollObject other = (PollObject) obj;
		if (this.active != other.active) {
			return false;
		}
		if (this.fixes == null) {
			if (other.fixes != null) {
				return false;
			}
		} else if (!this.fixes.equals(other.fixes)) {
			return false;
		}
		if (this.skyviews == null) {
			if (other.skyviews != null) {
				return false;
			}
		} else if (!this.skyviews.equals(other.skyviews)) {
			return false;
		}
		if (this.gst == null) {
			if (other.gst != null) {
				return false;
			}
		} else if (!this.gst.equals(other.gst)) {
			return false;
		}
		if (Double.doubleToLongBits(this.timestamp) != Double.doubleToLongBits(other.timestamp)) {
			return false;
		}
		return true;
	}
	
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		
		sb.append("PollObject{timestamp=");
		sb.append(this.timestamp);
		sb.append(", active=");
		sb.append(this.active);
		sb.append(", fixes=");
		sb.append(((this.fixes == null) ? 0 : this.fixes.size()));
		sb.append(", skyviews=");
		sb.append(((this.skyviews == null) ? 0 : this.skyviews.size()));
		sb.append(", gst=");
		sb.append(((this.gst == null) ? 0 : this.gst.size()));
		sb.append("}");
		
		return sb.toString();
	}
} public class SATObject implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "SAT";
	
	private int PRN = -1;
	
	private int azimuth = -1;
	
	private int elevation = -1;
	
	private int signalStrength = -1;
	
	private boolean used = false;
	
	/**
	 * PRN ID of the satellite. 1-63 are GNSS satellites, 64-96 are GLONASS satellites, 100-164 are SBAS satellites
	 *
	 * @return PRN
	 */
	public int getPRN() {
		return this.PRN;
	}
	
	/**
	 * PRN ID of the satellite. 1-63 are GNSS satellites, 64-96 are GLONASS satellites, 100-164 are SBAS satellites
	 *
	 * @param PRN the PRN to set
	 */
	public void setPRN(final int PRN) {
		this.PRN = PRN;
	}
	
	/**
	 * Azimuth, degrees from true north.
	 *
	 * @return azimuth
	 */
	public int getAzimuth() {
		return this.azimuth;
	}
	
	/**
	 * Azimuth, degrees from true north.
	 *
	 * @param azimuth the azimuth to set
	 */
	public void setAzimuth(final int azimuth) {
		this.azimuth = azimuth;
	}
	
	/**
	 * Elevation in degrees.
	 *
	 * @return elevation
	 */
	public int getElevation() {
		return this.elevation;
	}
	
	/**
	 * Elevation in degrees.
	 *
	 * @param elevation the elevation to set
	 */
	public void setElevation(final int elevation) {
		this.elevation = elevation;
	}
	
	/**
	 * Signal strength in dB.
	 *
	 * @return signal strength
	 */
	public int getSignalStrength() {
		return this.signalStrength;
	}
	
	/**
	 * Signal strength in dB.
	 *
	 * @param signalStrength the signal strength to set
	 */
	public void setSignalStrength(final int signalStrength) {
		this.signalStrength = signalStrength;
	}
	
	/**
	 * Used in current solution? (SBAS/WAAS/EGNOS satellites may be flagged used if the solution has corrections from them, but not all
	 * drivers make this information available.)
	 *
	 * @return used
	 */
	public boolean getUsed() {
		return this.used;
	}
	
	/**
	 * Used in current solution? (SBAS/WAAS/EGNOS satellites may be flagged used if the solution has corrections from them, but not all
	 * drivers make this information available.)
	 *
	 * @param used the used flag to set
	 */
	public void setUsed(final boolean used) {
		this.used = used;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		long temp;
		temp = Double.doubleToLongBits(this.PRN);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.azimuth);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.elevation);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.signalStrength);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		result = (prime * result) + ((this.used) ? 1 : 0);
		return result;
	}
	
	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (this.getClass() != obj.getClass()) {
			return false;
		}
		final SATObject other = (SATObject) obj;
		if (Double.doubleToLongBits(this.PRN) != Double.doubleToLongBits(other.PRN)) {
			return false;
		}
		if (Double.doubleToLongBits(this.azimuth) != Double.doubleToLongBits(other.azimuth)) {
			return false;
		}
		if (Double.doubleToLongBits(this.elevation) != Double.doubleToLongBits(other.elevation)) {
			return false;
		}
		if (Double.doubleToLongBits(this.signalStrength) != Double.doubleToLongBits(other.signalStrength)) {
			return false;
		}
		if (this.used != other.used) {
			return false;
		}
		return true;
	}
	
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		sb.append("SATObject{PRN=");
		sb.append(this.PRN);
		sb.append(", az=");
		sb.append(this.azimuth);
		sb.append(", el=");
		sb.append(this.elevation);
		sb.append(", ss=");
		sb.append(this.signalStrength);
		sb.append(", used=");
		sb.append(this.used ? "Y" : "N");
		sb.append("}");
		return sb.toString();
	}
} public class SKYObject implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "SKY";
	
	private String tag = null;
	
	private String device = null;
	
	private double timestamp = Double.NaN;
	
	private double longitudeDOP = Double.NaN;
	
	private double latitudeDOP = Double.NaN;
	
	private double altitudeDOP = Double.NaN;
	
	private double timestampDOP = Double.NaN;
	
	private double horizontalDOP = Double.NaN;
	
	private double sphericalDOP = Double.NaN;
	
	private double hypersphericalDOP = Double.NaN;
	
	private List<SATObject> satellites;
	
	/**
	 * Type tag associated with this GPS sentence; from an NMEA device this is just the NMEA sentence type.
	 *
	 * @return the tag
	 */
	public String getTag() {
		return this.tag;
	}
	
	/**
	 * Type tag associated with this GPS sentence; from an NMEA device this is just the NMEA sentence type.
	 *
	 * @param tag the tag to set
	 */
	public void setTag(final String tag) {
		this.tag = tag;
	}
	
	/**
	 * Name of originating device
	 *
	 * @return the device
	 */
	public String getDevice() {
		return this.device;
	}
	
	/**
	 * Name of originating device
	 *
	 * @param device the device to set
	 */
	public void setDevice(final String device) {
		this.device = device;
	}
	
	/**
	 * Seconds since the Unix epoch, UTC. May have a fractional part of up to .01sec precision.
	 *
	 * @return the timestamp
	 */
	public double getTimestamp() {
		return this.timestamp;
	}
	
	/**
	 * Seconds since the Unix epoch, UTC. May have a fractional part of up to .01sec precision.
	 *
	 * @param timestamp the timestamp to set
	 */
	public void setTimestamp(final double timestamp) {
		this.timestamp = timestamp;
	}
	
	/**
	 * Longitudinal dilution of precision, a dimensionless factor which should be multiplied by a base UERE to get an error estimate.
	 *
	 * @return the longitude DOP
	 */
	public double getLongitudeDOP() {
		return this.longitudeDOP;
	}
	
	/**
	 * Longitudinal dilution of precision, a dimensionless factor which should be multiplied by a base UERE to get an error estimate.
	 *
	 * @param longitudeDOP the longitude DOP to set
	 */
	public void setLongitudeDOP(final double longitudeDOP) {
		this.longitudeDOP = longitudeDOP;
	}
	
	/**
	 * Latitudinal dilution of precision, a dimensionless factor which should be multiplied by a base UERE to get an error estimate.
	 *
	 * @return the latitude DOP
	 */
	public double getLatitudeDOP() {
		return this.latitudeDOP;
	}
	
	/**
	 * Latitudinal dilution of precision, a dimensionless factor which should be multiplied by a base UERE to get an error estimate.
	 *
	 * @param latitudeDOP the latitude DOP to set
	 */
	public void setLatitudeDOP(final double latitudeDOP) {
		this.latitudeDOP = latitudeDOP;
	}
	
	/**
	 * Altitude dilution of precision, a dimensionless factor which should be multiplied by a base UERE to get an error estimate.
	 *
	 * @return the altitude DOP
	 */
	public double getAltitudeDOP() {
		return this.altitudeDOP;
	}
	
	/**
	 * Altitude dilution of precision, a dimensionless factor which should be multiplied by a base UERE to get an error estimate.
	 *
	 * @param altitudeDOP the altitude DOP to set
	 */
	public void setAltitudeDOP(final double altitudeDOP) {
		this.altitudeDOP = altitudeDOP;
	}
	
	/**
	 * Time dilution of precision, a dimensionless factor which should be multiplied by a base UERE to get an error estimate.
	 *
	 * @return the timestamp DOP
	 */
	public double getTimestampDOP() {
		return this.timestampDOP;
	}
	
	/**
	 * Time dilution of precision, a dimensionless factor which should be multiplied by a base UERE to get an error estimate.
	 *
	 * @param timestampDOP the timestamp DOP to set
	 */
	public void setTimestampDOP(final double timestampDOP) {
		this.timestampDOP = timestampDOP;
	}
	
	/**
	 * Horizontal dilution of precision, a dimensionless factor which should be multiplied by a base UERE to get a circular error estimate.
	 *
	 * @return the horizontal DOP
	 */
	public double getHorizontalDOP() {
		return this.horizontalDOP;
	}
	
	/**
	 * Horizontal dilution of precision, a dimensionless factor which should be multiplied by a base UERE to get a circular error estimate.
	 *
	 * @param horizontalDOP the horizontal DOP to set
	 */
	public void setHorizontalDOP(final double horizontalDOP) {
		this.horizontalDOP = horizontalDOP;
	}
	
	/**
	 * Spherical dilution of precision, a dimensionless factor which should be multiplied by a base UERE to get an error estimate.
	 *
	 * @return the spherical DOP
	 */
	public double getSphericalDOP() {
		return this.sphericalDOP;
	}
	
	/**
	 * Spherical dilution of precision, a dimensionless factor which should be multiplied by a base UERE to get an error estimate.
	 *
	 * @param sphericalDOP the spherical DOP to set
	 */
	public void setSphericalDOP(final double sphericalDOP) {
		this.sphericalDOP = sphericalDOP;
	}
	
	/**
	 * Hyperspherical dilution of precision, a dimensionless factor which should be multiplied by a base UERE to get an error estimate.
	 *
	 * @return the hyperspherical DOP
	 */
	public double getHypersphericalDOP() {
		return this.hypersphericalDOP;
	}
	
	/**
	 * Hyperspherical dilution of precision, a dimensionless factor which should be multiplied by a base UERE to get an error estimate.
	 *
	 * @param hypersphericalDOP the hyperspherical DOP to set
	 */
	public void setHypersphericalDOP(final double hypersphericalDOP) {
		this.hypersphericalDOP = hypersphericalDOP;
	}
	
	/**
	 * list of Satellite objects
	 *
	 * @return the satellites
	 */
	public List<SATObject> getSatellites() {
		return this.satellites;
	}
	
	/**
	 * list of Satellite objects
	 *
	 * @param satellites the satellites to set
	 */
	public void setSatellites(final List<SATObject> satellites) {
		this.satellites = satellites;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		long temp;
		temp = Double.doubleToLongBits(this.altitudeDOP);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		result = (prime * result) + ((this.device == null) ? 0 : this.device.hashCode());
		temp = Double.doubleToLongBits(this.horizontalDOP);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.hypersphericalDOP);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.latitudeDOP);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.longitudeDOP);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.sphericalDOP);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		result = (prime * result) + ((this.tag == null) ? 0 : this.tag.hashCode());
		temp = Double.doubleToLongBits(this.timestamp);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.timestampDOP);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		return result;
	}
	
	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (this.getClass() != obj.getClass()) {
			return false;
		}
		final SKYObject other = (SKYObject) obj;
		if (Double.doubleToLongBits(this.altitudeDOP) != Double.doubleToLongBits(other.altitudeDOP)) {
			return false;
		}
		if (this.device == null) {
			if (other.device != null) {
				return false;
			}
		} else if (!this.device.equals(other.device)) {
			return false;
		}
		if (Double.doubleToLongBits(this.horizontalDOP) != Double.doubleToLongBits(other.horizontalDOP)) {
			return false;
		}
		if (Double.doubleToLongBits(this.hypersphericalDOP) != Double.doubleToLongBits(other.hypersphericalDOP)) {
			return false;
		}
		if (Double.doubleToLongBits(this.latitudeDOP) != Double.doubleToLongBits(other.latitudeDOP)) {
			return false;
		}
		if (Double.doubleToLongBits(this.longitudeDOP) != Double.doubleToLongBits(other.longitudeDOP)) {
			return false;
		}
		if (Double.doubleToLongBits(this.sphericalDOP) != Double.doubleToLongBits(other.sphericalDOP)) {
			return false;
		}
		if (this.tag == null) {
			if (other.tag != null) {
				return false;
			}
		} else if (!this.tag.equals(other.tag)) {
			return false;
		}
		if (Double.doubleToLongBits(this.timestamp) != Double.doubleToLongBits(other.timestamp)) {
			return false;
		}
		if (Double.doubleToLongBits(this.timestampDOP) != Double.doubleToLongBits(other.timestampDOP)) {
			return false;
		}
		if (this.satellites.size() != other.satellites.size()) {
			return false;
		}
		try {
			for (int i = 0; i < this.satellites.size(); i++) {
				if (!this.satellites.get(i).equals(other.satellites.get(i))) {
					return false;
				}
			}
		} catch (final IndexOutOfBoundsException e) {
			return false;
		}
		
		return true;
	}
	
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		sb.append("SKYObject{time=");
		sb.append(this.timestamp);
		sb.append(", xdop=");
		sb.append(this.longitudeDOP);
		sb.append(", ydop=");
		sb.append(this.latitudeDOP);
		sb.append(", vdop=");
		sb.append(this.altitudeDOP);
		sb.append(", tdop=");
		sb.append(this.timestampDOP);
		sb.append(", hdop=");
		sb.append(this.horizontalDOP);
		sb.append(", pdop=");
		sb.append(this.sphericalDOP);
		sb.append(", gdop=");
		sb.append(this.hypersphericalDOP);
		sb.append(", sat=");
		sb.append(this.satellites == null ? 0 : this.satellites.size());
		sb.append("}");
		
		return sb.toString();
	}
	
} public class TPVObject implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "TPV";
	
	private String tag = null;
	
	private String device = null;
	
	private double timestamp = Double.NaN;
	
	private double timestampError = Double.NaN;
	
	private double latitude = Double.NaN;
	
	private double longitude = Double.NaN;
	
	private double altitude = Double.NaN;
	
	private double latitudeError = Double.NaN;
	
	private double longitudeError = Double.NaN;
	
	private double altitudeError = Double.NaN;
	
	private double course = Double.NaN;
	
	private double speed = Double.NaN;
	
	private double climbRate = Double.NaN;
	
	private double courseError = Double.NaN;
	
	private double speedError = Double.NaN;
	
	private double climbRateError = Double.NaN;
	
	private ENMEAMode mode;
	
	/**
	 * Type tag associated with this GPS sentence; from an NMEA device this is just the NMEA sentence type.
	 *
	 * @return the tag
	 */
	public String getTag() {
		return this.tag;
	}
	
	/**
	 * Type tag associated with this GPS sentence; from an NMEA device this is just the NMEA sentence type.
	 *
	 * @param tag the tag to set
	 */
	public void setTag(final String tag) {
		this.tag = tag;
	}
	
	/**
	 * Name of originating device
	 *
	 * @return the device
	 */
	public String getDevice() {
		return this.device;
	}
	
	/**
	 * Name of originating device
	 *
	 * @param device the device to set
	 */
	public void setDevice(final String device) {
		this.device = device;
	}
	
	/**
	 * Seconds since the Unix epoch, UTC. May have a fractional part of up to .01sec precision.
	 *
	 * @return the timestamp
	 */
	public double getTimestamp() {
		return this.timestamp;
	}
	
	/**
	 * Seconds since the Unix epoch, UTC. May have a fractional part of up to .01sec precision.
	 *
	 * @param timestamp the timestamp to set
	 */
	public void setTimestamp(final double timestamp) {
		this.timestamp = timestamp;
	}
	
	/**
	 * Estimated timestamp error (%f, seconds, 95% confidence).
	 *
	 * @return the timestampError
	 */
	public double getTimestampError() {
		return this.timestampError;
	}
	
	/**
	 * Estimated timestamp error (%f, seconds, 95% confidence).
	 *
	 * @param timestampError the timestampError to set
	 */
	public void setTimestampError(final double timestampError) {
		this.timestampError = timestampError;
	}
	
	/**
	 * Latitude in degrees: +/- signifies North/South
	 *
	 * @return the latitude
	 */
	public double getLatitude() {
		return this.latitude;
	}
	
	/**
	 * Latitude in degrees: +/- signifies North/South
	 *
	 * @param latitude the latitude to set
	 */
	public void setLatitude(final double latitude) {
		this.latitude = latitude;
	}
	
	/**
	 * Longitude in degrees: +/- signifies East/West
	 *
	 * @return the longitude
	 */
	public double getLongitude() {
		return this.longitude;
	}
	
	/**
	 * Longitude in degrees: +/- signifies East/West
	 *
	 * @param longitude the longitude to set
	 */
	public void setLongitude(final double longitude) {
		this.longitude = longitude;
	}
	
	/**
	 * Altitude in meters.
	 *
	 * @return the altitude
	 */
	public double getAltitude() {
		return this.altitude;
	}
	
	/**
	 * Altitude in meters.
	 *
	 * @param altitude the altitude to set
	 */
	public void setAltitude(final double altitude) {
		this.altitude = altitude;
	}
	
	/**
	 * Latitude error estimate in meters, 95% confidence.
	 *
	 * @return the latitudeError
	 */
	public double getLatitudeError() {
		return this.latitudeError;
	}
	
	/**
	 * Latitude error estimate in meters, 95% confidence.
	 *
	 * @param latitudeError the latitudeError to set
	 */
	public void setLatitudeError(final double latitudeError) {
		this.latitudeError = latitudeError;
	}
	
	/**
	 * Longitude error estimate in meters, 95% confidence.
	 *
	 * @return the longitudeError
	 */
	public double getLongitudeError() {
		return this.longitudeError;
	}
	
	/**
	 * Longitude error estimate in meters, 95% confidence.
	 *
	 * @param longitudeError the longitudeError to set
	 */
	public void setLongitudeError(final double longitudeError) {
		this.longitudeError = longitudeError;
	}
	
	/**
	 * Estimated vertical error in meters, 95% confidence.
	 *
	 * @return the altitudeError
	 */
	public double getAltitudeError() {
		return this.altitudeError;
	}
	
	/**
	 * Estimated vertical error in meters, 95% confidence.
	 *
	 * @param altitudeError the altitudeError to set
	 */
	public void setAltitudeError(final double altitudeError) {
		this.altitudeError = altitudeError;
	}
	
	/**
	 * Course over ground, degrees from true north.
	 *
	 * @return the course
	 */
	public double getCourse() {
		return this.course;
	}
	
	/**
	 * Course over ground, degrees from true north.
	 *
	 * @param course the course to set
	 */
	public void setCourse(final double course) {
		this.course = course;
	}
	
	/**
	 * Speed over ground, meters per second.
	 *
	 * @return the speed
	 */
	public double getSpeed() {
		return this.speed;
	}
	
	/**
	 * Speed over ground, meters per second.
	 *
	 * @param speed the speed to set
	 */
	public void setSpeed(final double speed) {
		this.speed = speed;
	}
	
	/**
	 * Climb (positive) or sink (negative) rate, meters per second.
	 *
	 * @return the climbRate
	 */
	public double getClimbRate() {
		return this.climbRate;
	}
	
	/**
	 * Climb (positive) or sink (negative) rate, meters per second.
	 *
	 * @param climbRate the climbRate to set
	 */
	public void setClimbRate(final double climbRate) {
		this.climbRate = climbRate;
	}
	
	/**
	 * Direction error estimate in degrees, 95% confidence.
	 *
	 * @return the courseError
	 */
	public double getCourseError() {
		return this.courseError;
	}
	
	/**
	 * Direction error estimate in degrees, 95% confidence.
	 *
	 * @param courseError the courseError to set
	 */
	public void setCourseError(final double courseError) {
		this.courseError = courseError;
	}
	
	/**
	 * Speed error estimate in meters/sec, 95% confidence.
	 *
	 * @return the speedError
	 */
	public double getSpeedError() {
		return this.speedError;
	}
	
	/**
	 * Speed error estimate in meters/sec, 95% confidence.
	 *
	 * @param speedError the speedError to set
	 */
	public void setSpeedError(final double speedError) {
		this.speedError = speedError;
	}
	
	/**
	 * Climb/sink error estimate in meters/sec, 95% confidence.
	 *
	 * @return the climbRateError
	 */
	public double getClimbRateError() {
		return this.climbRateError;
	}
	
	/**
	 * Climb/sink error estimate in meters/sec, 95% confidence.
	 *
	 * @param climbRateError the climbRateError to set
	 */
	public void setClimbRateError(final double climbRateError) {
		this.climbRateError = climbRateError;
	}
	
	/**
	 * NMEA mode
	 *
	 * @return the mode
	 */
	public ENMEAMode getMode() {
		return this.mode;
	}
	
	/**
	 * NMEA mode
	 *
	 * @param mode the mode to set
	 */
	public void setMode(final ENMEAMode mode) {
		this.mode = mode;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		long temp;
		temp = Double.doubleToLongBits(this.altitude);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.altitudeError);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.climbRate);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.climbRateError);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.course);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.courseError);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		result = (prime * result) + ((this.device == null) ? 0 : this.device.hashCode());
		temp = Double.doubleToLongBits(this.latitude);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.latitudeError);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.longitude);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.longitudeError);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		result = (prime * result) + ((this.mode == null) ? 0 : this.mode.hashCode());
		temp = Double.doubleToLongBits(this.speed);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.speedError);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		result = (prime * result) + ((this.tag == null) ? 0 : this.tag.hashCode());
		temp = Double.doubleToLongBits(this.timestamp);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.timestampError);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		return result;
	}
	
	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (this.getClass() != obj.getClass()) {
			return false;
		}
		final TPVObject other = (TPVObject) obj;
		if (Double.doubleToLongBits(this.altitude) != Double.doubleToLongBits(other.altitude)) {
			return false;
		}
		if (Double.doubleToLongBits(this.altitudeError) != Double.doubleToLongBits(other.altitudeError)) {
			return false;
		}
		if (Double.doubleToLongBits(this.climbRate) != Double.doubleToLongBits(other.climbRate)) {
			return false;
		}
		if (Double.doubleToLongBits(this.climbRateError) != Double.doubleToLongBits(other.climbRateError)) {
			return false;
		}
		if (Double.doubleToLongBits(this.course) != Double.doubleToLongBits(other.course)) {
			return false;
		}
		if (Double.doubleToLongBits(this.courseError) != Double.doubleToLongBits(other.courseError)) {
			return false;
		}
		if (this.device == null) {
			if (other.device != null) {
				return false;
			}
		} else if (!this.device.equals(other.device)) {
			return false;
		}
		if (Double.doubleToLongBits(this.latitude) != Double.doubleToLongBits(other.latitude)) {
			return false;
		}
		if (Double.doubleToLongBits(this.latitudeError) != Double.doubleToLongBits(other.latitudeError)) {
			return false;
		}
		if (Double.doubleToLongBits(this.longitude) != Double.doubleToLongBits(other.longitude)) {
			return false;
		}
		if (Double.doubleToLongBits(this.longitudeError) != Double.doubleToLongBits(other.longitudeError)) {
			return false;
		}
		if (this.mode != other.mode) {
			return false;
		}
		if (Double.doubleToLongBits(this.speed) != Double.doubleToLongBits(other.speed)) {
			return false;
		}
		if (Double.doubleToLongBits(this.speedError) != Double.doubleToLongBits(other.speedError)) {
			return false;
		}
		if (this.tag == null) {
			if (other.tag != null) {
				return false;
			}
		} else if (!this.tag.equals(other.tag)) {
			return false;
		}
		if (Double.doubleToLongBits(this.timestamp) != Double.doubleToLongBits(other.timestamp)) {
			return false;
		}
		if (Double.doubleToLongBits(this.timestampError) != Double.doubleToLongBits(other.timestampError)) {
			return false;
		}
		return true;
	}
	
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		sb.append("TPVObject{tag=");
		sb.append(this.tag);
		sb.append(", device=");
		sb.append(this.device);
		sb.append(", timestamp=");
		sb.append(this.timestamp);
		sb.append(", timestampError=");
		sb.append(this.timestampError);
		sb.append(", latitude=");
		sb.append(this.latitude);
		sb.append(", longitude=");
		sb.append(this.longitude);
		sb.append(", altitude=");
		sb.append(this.altitude);
		sb.append(", latitudeError=");
		sb.append(this.latitudeError);
		sb.append(", longitudeError=");
		sb.append(this.longitudeError);
		sb.append(", altitudeError=");
		sb.append(this.altitudeError);
		sb.append(", course=");
		sb.append(this.course);
		sb.append(", speed=");
		sb.append(this.speed);
		sb.append(", climbRate=");
		sb.append(this.climbRate);
		sb.append(", courseError=");
		sb.append(this.courseError);
		sb.append(", speedError=");
		sb.append(this.speedError);
		sb.append(", climbRateError=");
		sb.append(this.climbRateError);
		if (mode != null) {
			sb.append(", mode=");
			sb.append(this.mode.name());
		}
		sb.append("}");
		return sb.toString();
	}
	
} public class VersionObject implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "VERSION";
	
	private String release;
	
	private String rev;
	
	private double protocolMajor;
	
	private double protocolMinor;
	
	/**
	 * @return the release
	 */
	public String getRelease() {
		return this.release;
	}
	
	/**
	 * @param release the release to set
	 */
	public void setRelease(final String release) {
		this.release = release;
	}
	
	/**
	 * @return the rev
	 */
	public String getRev() {
		return this.rev;
	}
	
	/**
	 * @param rev the rev to set
	 */
	public void setRev(final String rev) {
		this.rev = rev;
	}
	
	/**
	 * @return the protocolMajor
	 */
	public double getProtocolMajor() {
		return this.protocolMajor;
	}
	
	/**
	 * @param protocolMajor the protocolMajor to set
	 */
	public void setProtocolMajor(final double protocolMajor) {
		this.protocolMajor = protocolMajor;
	}
	
	/**
	 * @return the protocolMinor
	 */
	public double getProtocolMinor() {
		return this.protocolMinor;
	}
	
	/**
	 * @param protocolMinor the protocolMinor to set
	 */
	public void setProtocolMinor(final double protocolMinor) {
		this.protocolMinor = protocolMinor;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		long temp;
		temp = Double.doubleToLongBits(this.protocolMajor);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(this.protocolMinor);
		result = (prime * result) + (int) (temp ^ (temp >>> 32));
		result = (prime * result) + ((this.release == null) ? 0 : this.release.hashCode());
		result = (prime * result) + ((this.rev == null) ? 0 : this.rev.hashCode());
		return result;
	}
	
	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (this.getClass() != obj.getClass()) {
			return false;
		}
		final VersionObject other = (VersionObject) obj;
		if (Double.doubleToLongBits(this.protocolMajor) != Double.doubleToLongBits(other.protocolMajor)) {
			return false;
		}
		if (Double.doubleToLongBits(this.protocolMinor) != Double.doubleToLongBits(other.protocolMinor)) {
			return false;
		}
		if (this.release == null) {
			if (other.release != null) {
				return false;
			}
		} else if (!this.release.equals(other.release)) {
			return false;
		}
		if (this.rev == null) {
			if (other.rev != null) {
				return false;
			}
		} else if (!this.rev.equals(other.rev)) {
			return false;
		}
		return true;
	}
	
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		
		sb.append("VersionObject{release=");
		sb.append(this.release);
		sb.append(", rev=");
		sb.append(this.rev);
		sb.append(", protocolMajor=");
		sb.append(this.protocolMajor);
		sb.append(", protocolMinor=");
		sb.append(this.protocolMinor);
		sb.append("}");
		return sb.toString();
	}
	
} public class WatchObject implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "WATCH";
	
	private boolean enable = true;
	
	private boolean dump = false;
	
	/**
	 * Enable (true) or disable (false) watcher mode. Default is true.
	 *
	 * @return the enable
	 */
	public boolean isEnable() {
		return this.enable;
	}
	
	/**
	 * Enable (true) or disable (false) watcher mode. Default is true.
	 *
	 * @param enable the enable to set
	 */
	public void setEnable(final boolean enable) {
		this.enable = enable;
	}
	
	/**
	 * Enable (true) or disable (false) dumping of JSON reports. Default is false.
	 *
	 * @return the json
	 */
	public boolean isDump() {
		return this.dump;
	}
	
	/**
	 * Enable (true) or disable (false) dumping of JSON reports. Default is false.
	 *
	 * @param dump the dump to set
	 */
	public void setDump(final boolean dump) {
		this.dump = dump;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = (prime * result) + (this.dump ? 1231 : 1237);
		result = (prime * result) + (this.enable ? 1231 : 1237);
		return result;
	}
	
	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (this.getClass() != obj.getClass()) {
			return false;
		}
		final WatchObject other = (WatchObject) obj;
		if (this.dump != other.dump) {
			return false;
		}
		if (this.enable != other.enable) {
			return false;
		}
		return true;
	}
	
	@Override
	public String toString() {
		return "WatchObject{enable=" + this.enable + ", dump=" + this.dump + "}";
	}
	
} public class ALMANACObject implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "ALMANAC";
	
	private int ID = -1;
	
	private int Health = -1;
	
	private double e = Double.NaN;
	
	private int toa = -1;
	
	private double deltai = Double.NaN;
	
	private double Omegad = Double.NaN;
	
	private double sqrtA = Double.NaN;
	
	private double Omega0 = Double.NaN;
	
	private double omega = Double.NaN;
	
	private double M0 = Double.NaN;
	
	private double af0 = Double.NaN;
	
	private double af1 = Double.NaN;
	
	/**
	 * @return the iD
	 */
	public int getID() {
		return this.ID;
	}
	
	/**
	 * @param iD the iD to set
	 */
	public void setID(final int iD) {
		this.ID = iD;
	}
	
	/**
	 * @return the health
	 */
	public int getHealth() {
		return this.Health;
	}
	
	/**
	 * @param health the health to set
	 */
	public void setHealth(final int health) {
		this.Health = health;
	}
	
	/**
	 * @return the e
	 */
	public double getE() {
		return this.e;
	}
	
	/**
	 * @param e the e to set
	 */
	public void setE(final double e) {
		this.e = e;
	}
	
	/**
	 * @return the toa
	 */
	public int getToa() {
		return this.toa;
	}
	
	/**
	 * @param toa the toa to set
	 */
	public void setToa(final int toa) {
		this.toa = toa;
	}
	
	/**
	 * @return the deltai
	 */
	public double getDeltai() {
		return this.deltai;
	}
	
	/**
	 * @param deltai the deltai to set
	 */
	public void setDeltai(final double deltai) {
		this.deltai = deltai;
	}
	
	/**
	 * @return the omegad
	 */
	public double getOmegad() {
		return this.Omegad;
	}
	
	/**
	 * @param omegad the omegad to set
	 */
	public void setOmegad(final double omegad) {
		this.Omegad = omegad;
	}
	
	/**
	 * @return the sqrtA
	 */
	public double getSqrtA() {
		return this.sqrtA;
	}
	
	/**
	 * @param sqrtA the sqrtA to set
	 */
	public void setSqrtA(final double sqrtA) {
		this.sqrtA = sqrtA;
	}
	
	/**
	 * @return the omega0
	 */
	public double getOmega0() {
		return this.Omega0;
	}
	
	/**
	 * @param omega0 the omega0 to set
	 */
	public void setOmega0(final double omega0) {
		this.Omega0 = omega0;
	}
	
	/**
	 * @return the omega
	 */
	public double getOmega() {
		return this.omega;
	}
	
	/**
	 * @param omega the omega to set
	 */
	public void setOmega(final double omega) {
		this.omega = omega;
	}
	
	/**
	 * @return the m0
	 */
	public double getM0() {
		return this.M0;
	}
	
	/**
	 * @param m0 the m0 to set
	 */
	public void setM0(final double m0) {
		this.M0 = m0;
	}
	
	/**
	 * @return the af0
	 */
	public double getAf0() {
		return this.af0;
	}
	
	/**
	 * @param af0 the af0 to set
	 */
	public void setAf0(final double af0) {
		this.af0 = af0;
	}
	
	/**
	 * @return the af1
	 */
	public double getAf1() {
		return this.af1;
	}
	
	/**
	 * @param af1 the af1 to set
	 */
	public void setAf1(final double af1) {
		this.af1 = af1;
	}
	
	@Override
	public boolean equals(final Object o) {
		if (this == o) {
			return true;
		}
		if (!(o instanceof ALMANACObject)) {
			return false;
		}
		
		final ALMANACObject that = (ALMANACObject) o;
		
		if (this.Health != that.Health) {
			return false;
		}
		if (this.ID != that.ID) {
			return false;
		}
		if (Double.compare(that.M0, this.M0) != 0) {
			return false;
		}
		if (Double.compare(that.Omega0, this.Omega0) != 0) {
			return false;
		}
		if (Double.compare(that.Omegad, this.Omegad) != 0) {
			return false;
		}
		if (Double.compare(that.af0, this.af0) != 0) {
			return false;
		}
		if (Double.compare(that.af1, this.af1) != 0) {
			return false;
		}
		if (Double.compare(that.deltai, this.deltai) != 0) {
			return false;
		}
		if (Double.compare(that.e, this.e) != 0) {
			return false;
		}
		if (Double.compare(that.omega, this.omega) != 0) {
			return false;
		}
		if (Double.compare(that.sqrtA, this.sqrtA) != 0) {
			return false;
		}
		if (this.toa != that.toa) {
			return false;
		}
		
		return true;
	}
	
	@Override
	public int hashCode() {
		int result;
		long temp;
		result = this.ID;
		result = (31 * result) + this.Health;
		temp = this.e != +0.0d ? Double.doubleToLongBits(this.e) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		result = (31 * result) + this.toa;
		temp = this.deltai != +0.0d ? Double.doubleToLongBits(this.deltai) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.Omegad != +0.0d ? Double.doubleToLongBits(this.Omegad) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.sqrtA != +0.0d ? Double.doubleToLongBits(this.sqrtA) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.Omega0 != +0.0d ? Double.doubleToLongBits(this.Omega0) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.omega != +0.0d ? Double.doubleToLongBits(this.omega) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.M0 != +0.0d ? Double.doubleToLongBits(this.M0) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.af0 != +0.0d ? Double.doubleToLongBits(this.af0) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.af1 != +0.0d ? Double.doubleToLongBits(this.af1) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		return result;
	}
	
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		sb.append("ALMANACObject{ID=");
		sb.append(this.ID);
		sb.append(", Health=");
		sb.append(this.Health);
		sb.append(", e=");
		sb.append(this.e);
		sb.append(", toa=");
		sb.append(this.toa);
		sb.append(", deltai=");
		sb.append(this.deltai);
		sb.append(", Omegad=");
		sb.append(this.Omegad);
		sb.append(", sqrtA=");
		sb.append(this.sqrtA);
		sb.append(", Omega0=");
		sb.append(this.Omega0);
		sb.append(", omega=");
		sb.append(this.omega);
		sb.append(", M0=");
		sb.append(this.M0);
		sb.append(", af0=");
		sb.append(this.af0);
		sb.append(", af1=");
		sb.append(this.af1);
		sb.append("}");
		return sb.toString();
	}
} public class EPHEM1Object implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "EPHEM1";
	
	private int WN = -1;
	
	private int IODC = -1;
	
	private int L2 = -1;
	
	private double ura = Double.NaN;
	
	private double hlth = Double.NaN;
	
	private int L2P = -1;
	
	private double Tgd = Double.NaN;
	
	private int toc = -1;
	
	private double af2 = Double.NaN;
	
	private double af1 = Double.NaN;
	
	private double af0 = Double.NaN;
	
	/**
	 * @return the wN
	 */
	public int getWN() {
		return this.WN;
	}
	
	/**
	 * @param wN the wN to set
	 */
	public void setWN(final int wN) {
		this.WN = wN;
	}
	
	/**
	 * @return the iODC
	 */
	public int getIODC() {
		return this.IODC;
	}
	
	/**
	 * @param iODC the iODC to set
	 */
	public void setIODC(final int iODC) {
		this.IODC = iODC;
	}
	
	/**
	 * @return the l2
	 */
	public int getL2() {
		return this.L2;
	}
	
	/**
	 * @param l2 the l2 to set
	 */
	public void setL2(final int l2) {
		this.L2 = l2;
	}
	
	/**
	 * @return the ura
	 */
	public double getUra() {
		return this.ura;
	}
	
	/**
	 * @param ura the ura to set
	 */
	public void setUra(final double ura) {
		this.ura = ura;
	}
	
	/**
	 * @return the hlth
	 */
	public double getHlth() {
		return this.hlth;
	}
	
	/**
	 * @param hlth the hlth to set
	 */
	public void setHlth(final double hlth) {
		this.hlth = hlth;
	}
	
	/**
	 * @return the l2P
	 */
	public int getL2P() {
		return this.L2P;
	}
	
	/**
	 * @param l2p the l2P to set
	 */
	public void setL2P(final int l2p) {
		this.L2P = l2p;
	}
	
	/**
	 * @return the tgd
	 */
	public double getTgd() {
		return this.Tgd;
	}
	
	/**
	 * @param tgd the tgd to set
	 */
	public void setTgd(final double tgd) {
		this.Tgd = tgd;
	}
	
	/**
	 * @return the toc
	 */
	public int getToc() {
		return this.toc;
	}
	
	/**
	 * @param toc the toc to set
	 */
	public void setToc(final int toc) {
		this.toc = toc;
	}
	
	/**
	 * @return the af2
	 */
	public double getAf2() {
		return this.af2;
	}
	
	/**
	 * @param af2 the af2 to set
	 */
	public void setAf2(final double af2) {
		this.af2 = af2;
	}
	
	/**
	 * @return the af1
	 */
	public double getAf1() {
		return this.af1;
	}
	
	/**
	 * @param af1 the af1 to set
	 */
	public void setAf1(final double af1) {
		this.af1 = af1;
	}
	
	/**
	 * @return the af0
	 */
	public double getAf0() {
		return this.af0;
	}
	
	/**
	 * @param af0 the af0 to set
	 */
	public void setAf0(final double af0) {
		this.af0 = af0;
	}
	
	@Override
	public boolean equals(final Object o) {
		if (this == o) {
			return true;
		}
		if ((o == null) || (this.getClass() != o.getClass())) {
			return false;
		}
		
		final EPHEM1Object that = (EPHEM1Object) o;
		
		if (this.IODC != that.IODC) {
			return false;
		}
		if (this.L2 != that.L2) {
			return false;
		}
		if (this.L2P != that.L2P) {
			return false;
		}
		if (Double.compare(that.Tgd, this.Tgd) != 0) {
			return false;
		}
		if (this.WN != that.WN) {
			return false;
		}
		if (Double.compare(that.af0, this.af0) != 0) {
			return false;
		}
		if (Double.compare(that.af1, this.af1) != 0) {
			return false;
		}
		if (Double.compare(that.af2, this.af2) != 0) {
			return false;
		}
		if (Double.compare(that.hlth, this.hlth) != 0) {
			return false;
		}
		if (this.toc != that.toc) {
			return false;
		}
		if (Double.compare(that.ura, this.ura) != 0) {
			return false;
		}
		
		return true;
	}
	
	@Override
	public int hashCode() {
		int result;
		long temp;
		result = this.WN;
		result = (31 * result) + this.IODC;
		result = (31 * result) + this.L2;
		temp = this.ura != +0.0d ? Double.doubleToLongBits(this.ura) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.hlth != +0.0d ? Double.doubleToLongBits(this.hlth) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		result = (31 * result) + this.L2P;
		temp = this.Tgd != +0.0d ? Double.doubleToLongBits(this.Tgd) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		result = (31 * result) + this.toc;
		temp = this.af2 != +0.0d ? Double.doubleToLongBits(this.af2) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.af1 != +0.0d ? Double.doubleToLongBits(this.af1) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.af0 != +0.0d ? Double.doubleToLongBits(this.af0) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		return result;
	}
	
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		sb.append("EPHEM1Object{WN=");
		sb.append(this.WN);
		sb.append(", IODC=");
		sb.append(this.IODC);
		sb.append(", ura=");
		sb.append(this.ura);
		sb.append(", L2=");
		sb.append(this.L2);
		sb.append(", hlth=");
		sb.append(this.hlth);
		sb.append(", L2P=");
		sb.append(this.L2P);
		sb.append(", Tgd=");
		sb.append(this.Tgd);
		sb.append(", toc=");
		sb.append(this.toc);
		sb.append(", af2=");
		sb.append(this.af2);
		sb.append(", af0=");
		sb.append(this.af0);
		sb.append(", af1=");
		sb.append(this.af1);
		sb.append("}");
		return sb.toString();
	}
	
} public class EPHEM2Object implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "EPHEM2";
	
	private int IODE = -1;
	
	private double Crs = Double.NaN;
	
	private double deltan = Double.NaN;
	
	private double M0 = Double.NaN;
	
	private double Cuc = Double.NaN;
	
	private double e = Double.NaN;
	
	private double Cus = Double.NaN;
	
	private double sqrtA = Double.NaN;
	
	private int toe = -1;
	
	private int FIT = -1;
	
	private int AODO = -1;
	
	/**
	 * @return the iODE
	 */
	public int getIODE() {
		return this.IODE;
	}
	
	/**
	 * @param iODE the iODE to set
	 */
	public void setIODE(final int iODE) {
		this.IODE = iODE;
	}
	
	/**
	 * @return the crs
	 */
	public double getCrs() {
		return this.Crs;
	}
	
	/**
	 * @param crs the crs to set
	 */
	public void setCrs(final double crs) {
		this.Crs = crs;
	}
	
	/**
	 * @return the deltan
	 */
	public double getDeltan() {
		return this.deltan;
	}
	
	/**
	 * @param deltan the deltan to set
	 */
	public void setDeltan(final double deltan) {
		this.deltan = deltan;
	}
	
	/**
	 * @return the m0
	 */
	public double getM0() {
		return this.M0;
	}
	
	/**
	 * @param m0 the m0 to set
	 */
	public void setM0(final double m0) {
		this.M0 = m0;
	}
	
	/**
	 * @return the cuc
	 */
	public double getCuc() {
		return this.Cuc;
	}
	
	/**
	 * @param cuc the cuc to set
	 */
	public void setCuc(final double cuc) {
		this.Cuc = cuc;
	}
	
	/**
	 * @return the e
	 */
	public double getE() {
		return this.e;
	}
	
	/**
	 * @param e the e to set
	 */
	public void setE(final double e) {
		this.e = e;
	}
	
	/**
	 * @return the cus
	 */
	public double getCus() {
		return this.Cus;
	}
	
	/**
	 * @param cus the cus to set
	 */
	public void setCus(final double cus) {
		this.Cus = cus;
	}
	
	/**
	 * @return the sqrtA
	 */
	public double getSqrtA() {
		return this.sqrtA;
	}
	
	/**
	 * @param sqrtA the sqrtA to set
	 */
	public void setSqrtA(final double sqrtA) {
		this.sqrtA = sqrtA;
	}
	
	/**
	 * @return the toe
	 */
	public int getToe() {
		return this.toe;
	}
	
	/**
	 * @param toe the toe to set
	 */
	public void setToe(final int toe) {
		this.toe = toe;
	}
	
	/**
	 * @return the fIT
	 */
	public int getFIT() {
		return this.FIT;
	}
	
	/**
	 * @param fIT the fIT to set
	 */
	public void setFIT(final int fIT) {
		this.FIT = fIT;
	}
	
	/**
	 * @return the aODO
	 */
	public int getAODO() {
		return this.AODO;
	}
	
	/**
	 * @param aODO the aODO to set
	 */
	public void setAODO(final int aODO) {
		this.AODO = aODO;
	}
	
	@Override
	public boolean equals(final Object o) {
		if (this == o) {
			return true;
		}
		if ((o == null) || (this.getClass() != o.getClass())) {
			return false;
		}
		
		final EPHEM2Object that = (EPHEM2Object) o;
		
		if (this.AODO != that.AODO) {
			return false;
		}
		if (Double.compare(that.Crs, this.Crs) != 0) {
			return false;
		}
		if (Double.compare(that.Cuc, this.Cuc) != 0) {
			return false;
		}
		if (Double.compare(that.Cus, this.Cus) != 0) {
			return false;
		}
		if (this.FIT != that.FIT) {
			return false;
		}
		if (this.IODE != that.IODE) {
			return false;
		}
		if (Double.compare(that.M0, this.M0) != 0) {
			return false;
		}
		if (Double.compare(that.deltan, this.deltan) != 0) {
			return false;
		}
		if (Double.compare(that.e, this.e) != 0) {
			return false;
		}
		if (Double.compare(that.sqrtA, this.sqrtA) != 0) {
			return false;
		}
		if (this.toe != that.toe) {
			return false;
		}
		
		return true;
	}
	
	@Override
	public int hashCode() {
		int result;
		long temp;
		result = this.IODE;
		temp = this.Crs != +0.0d ? Double.doubleToLongBits(this.Crs) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.deltan != +0.0d ? Double.doubleToLongBits(this.deltan) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.M0 != +0.0d ? Double.doubleToLongBits(this.M0) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.Cuc != +0.0d ? Double.doubleToLongBits(this.Cuc) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.e != +0.0d ? Double.doubleToLongBits(this.e) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.Cus != +0.0d ? Double.doubleToLongBits(this.Cus) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.sqrtA != +0.0d ? Double.doubleToLongBits(this.sqrtA) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		result = (31 * result) + this.toe;
		result = (31 * result) + this.FIT;
		result = (31 * result) + this.AODO;
		return result;
	}
	
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		sb.append("EPHEM2Object{IODE=");
		sb.append(this.IODE);
		sb.append(", Crs=");
		sb.append(this.Crs);
		sb.append(", deltan=");
		sb.append(this.deltan);
		sb.append(", M0=");
		sb.append(this.M0);
		sb.append(", Cuc=");
		sb.append(this.Cuc);
		sb.append(", e=");
		sb.append(this.e);
		sb.append(", Cus=");
		sb.append(this.Cus);
		sb.append(", sqrtA=");
		sb.append(this.sqrtA);
		sb.append(", toe=");
		sb.append(this.toe);
		sb.append(", FIT=");
		sb.append(this.FIT);
		sb.append(", AODO=");
		sb.append(this.AODO);
		sb.append("}");
		return sb.toString();
	}
	
} public class EPHEM3Object implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "EPHEM3";
	
	private int IODE = -1;
	
	private double IDOT = Double.NaN;
	
	private double Cic = Double.NaN;
	
	private double Omega0 = Double.NaN;
	
	private double Cis = Double.NaN;
	
	private double i0 = Double.NaN;
	
	private double Crc = Double.NaN;
	
	private double omega = Double.NaN;
	
	private double Omegad = Double.NaN;
	
	/**
	 * @return the iODE
	 */
	public int getIODE() {
		return this.IODE;
	}
	
	/**
	 * @param iODE the iODE to set
	 */
	public void setIODE(final int iODE) {
		this.IODE = iODE;
	}
	
	/**
	 * @return the iDOT
	 */
	public double getIDOT() {
		return this.IDOT;
	}
	
	/**
	 * @param iDOT the iDOT to set
	 */
	public void setIDOT(final double iDOT) {
		this.IDOT = iDOT;
	}
	
	/**
	 * @return the cic
	 */
	public double getCic() {
		return this.Cic;
	}
	
	/**
	 * @param cic the cic to set
	 */
	public void setCic(final double cic) {
		this.Cic = cic;
	}
	
	/**
	 * @return the omega0
	 */
	public double getOmega0() {
		return this.Omega0;
	}
	
	/**
	 * @param omega0 the omega0 to set
	 */
	public void setOmega0(final double omega0) {
		this.Omega0 = omega0;
	}
	
	/**
	 * @return the cis
	 */
	public double getCis() {
		return this.Cis;
	}
	
	/**
	 * @param cis the cis to set
	 */
	public void setCis(final double cis) {
		this.Cis = cis;
	}
	
	/**
	 * @return the i0
	 */
	public double getI0() {
		return this.i0;
	}
	
	/**
	 * @param i0 the i0 to set
	 */
	public void setI0(final double i0) {
		this.i0 = i0;
	}
	
	/**
	 * @return the crc
	 */
	public double getCrc() {
		return this.Crc;
	}
	
	/**
	 * @param crc the crc to set
	 */
	public void setCrc(final double crc) {
		this.Crc = crc;
	}
	
	/**
	 * @return the omega
	 */
	public double getOmega() {
		return this.omega;
	}
	
	/**
	 * @param omega the omega to set
	 */
	public void setOmega(final double omega) {
		this.omega = omega;
	}
	
	/**
	 * @return the omegad
	 */
	public double getOmegad() {
		return this.Omegad;
	}
	
	/**
	 * @param omegad the omegad to set
	 */
	public void setOmegad(final double omegad) {
		this.Omegad = omegad;
	}
	
	@Override
	public boolean equals(final Object o) {
		if (this == o) {
			return true;
		}
		if (!(o instanceof EPHEM3Object)) {
			return false;
		}
		
		final EPHEM3Object that = (EPHEM3Object) o;
		
		if (Double.compare(that.Cic, this.Cic) != 0) {
			return false;
		}
		if (Double.compare(that.Cis, this.Cis) != 0) {
			return false;
		}
		if (Double.compare(that.Crc, this.Crc) != 0) {
			return false;
		}
		if (Double.compare(that.IDOT, this.IDOT) != 0) {
			return false;
		}
		if (this.IODE != that.IODE) {
			return false;
		}
		if (Double.compare(that.Omega0, this.Omega0) != 0) {
			return false;
		}
		if (Double.compare(that.Omegad, this.Omegad) != 0) {
			return false;
		}
		if (Double.compare(that.i0, this.i0) != 0) {
			return false;
		}
		if (Double.compare(that.omega, this.omega) != 0) {
			return false;
		}
		
		return true;
	}
	
	@Override
	public int hashCode() {
		int result;
		long temp;
		result = this.IODE;
		temp = this.IDOT != +0.0d ? Double.doubleToLongBits(this.IDOT) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.Cic != +0.0d ? Double.doubleToLongBits(this.Cic) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.Omega0 != +0.0d ? Double.doubleToLongBits(this.Omega0) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.Cis != +0.0d ? Double.doubleToLongBits(this.Cis) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.i0 != +0.0d ? Double.doubleToLongBits(this.i0) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.Crc != +0.0d ? Double.doubleToLongBits(this.Crc) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.omega != +0.0d ? Double.doubleToLongBits(this.omega) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.Omegad != +0.0d ? Double.doubleToLongBits(this.Omegad) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		return result;
	}
	
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		sb.append("EPHEM3Object{IODE=");
		sb.append(this.IODE);
		sb.append(", IDOT=");
		sb.append(this.IDOT);
		sb.append(", Cic=");
		sb.append(this.Cic);
		sb.append(", Omega0=");
		sb.append(this.Omega0);
		sb.append(", Cis=");
		sb.append(this.Cis);
		sb.append(", i0=");
		sb.append(this.i0);
		sb.append(", Crc=");
		sb.append(this.Crc);
		sb.append(", omega=");
		sb.append(this.omega);
		sb.append(", Omegad=");
		sb.append(this.Omegad);
		sb.append("}");
		return sb.toString();
	}
	
} public class ERDObject implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "ERD";
	
	private int[] ERD = new int[30];
	
	private int ai = -1;
	
	/**
	 * @return the eRD
	 */
	public int[] getERD() {
		return this.ERD;
	}
	
	/**
	 * @param eRD the eRD to set
	 */
	public void setERD(final int[] eRD) {
		this.ERD = eRD;
	}
	
	/**
	 * @return the ai
	 */
	public int getAi() {
		return this.ai;
	}
	
	/**
	 * @param ai the ai to set
	 */
	public void setAi(final int ai) {
		this.ai = ai;
	}
	
	/**
	 * @param index
	 * @return the ERD
	 */
	public int getERDbyIndex(final int index) {
		return this.ERD[index];
	}
	
	/**
	 * @param index    the index
	 * @param ERDvalue the ERD
	 */
	public void setERDbyIndex(final int index, final int ERDvalue) {
		this.ERD[index] = ERDvalue;
	}
	
	@Override
	public boolean equals(final Object o) {
		if (this == o) {
			return true;
		}
		if (!(o instanceof ERDObject)) {
			return false;
		}
		
		final ERDObject erdObject = (ERDObject) o;
		
		if (this.ai != erdObject.ai) {
			return false;
		}
		if (!Arrays.equals(this.ERD, erdObject.ERD)) {
			return false;
		}
		
		return true;
	}
	
	@Override
	public int hashCode() {
		int result = this.ERD != null ? Arrays.hashCode(this.ERD) : 0;
		result = (31 * result) + this.ai;
		return result;
	}
	
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		sb.append("ERDObject{ai=");
		sb.append(this.ai);
		for (int index = 1; index <= 30; index++) {
			sb.append(", ERD");
			sb.append(index);
			sb.append("=");
			sb.append(this.ERD[index - 1]);
		}
		sb.append("}");
		return sb.toString();
	}
	
} public class HEALTH2Object implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "HEALTH2";
	
	private final int[] SV = new int[24];
	
	private int toa = -1;
	
	private int WNa = -1;
	
	/**
	 * @return the toa
	 */
	public int getToa() {
		return this.toa;
	}
	
	/**
	 * @param toa the toa to set
	 */
	public void setToa(final int toa) {
		this.toa = toa;
	}
	
	/**
	 * @return the wNa
	 */
	public int getWNa() {
		return this.WNa;
	}
	
	/**
	 * @param wNa the wNa to set
	 */
	public void setWNa(final int wNa) {
		this.WNa = wNa;
	}
	
	/**
	 * @param index the index
	 * @return the SV
	 */
	public int getSVbyIndex(final int index) {
		return this.SV[index];
	}
	
	/**
	 * @param index   the index
	 * @param SVvalue the SV
	 */
	public void setSVbyIndex(final int index, final int SVvalue) {
		this.SV[index] = SVvalue;
	}
	
	@Override
	public boolean equals(final Object o) {
		if (this == o) {
			return true;
		}
		if (!(o instanceof HEALTH2Object)) {
			return false;
		}
		
		final HEALTH2Object that = (HEALTH2Object) o;
		
		if (this.WNa != that.WNa) {
			return false;
		}
		if (this.toa != that.toa) {
			return false;
		}
		if (!Arrays.equals(this.SV, that.SV)) {
			return false;
		}
		
		return true;
	}
	
	@Override
	public int hashCode() {
		int result = this.SV != null ? Arrays.hashCode(this.SV) : 0;
		result = (31 * result) + this.toa;
		result = (31 * result) + this.WNa;
		return result;
	}
	
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		sb.append("HEALTH2Object{toa=");
		sb.append(this.toa);
		sb.append(", WNa=");
		sb.append(this.WNa);
		for (int index = 1; index <= 24; index++) {
			sb.append(", SV");
			sb.append(index);
			sb.append("=");
			sb.append(this.SV[index - 1]);
		}
		sb.append("}");
		return sb.toString();
	}
	
} public class HEALTHObject implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "HEALTH";
	
	private final int[] SV = new int[32];
	
	private final int[] SVH = new int[8];
	
	private int data_id = -1;
	
	/**
	 * @return the data_id
	 */
	public int getData_id() {
		return this.data_id;
	}
	
	/**
	 * @param data_id the data_id to set
	 */
	public void setData_id(final int data_id) {
		this.data_id = data_id;
	}
	
	/**
	 * @param index the index
	 * @return the SV
	 */
	public int getSVbyIndex(final int index) {
		return this.SV[index];
	}
	
	/**
	 * @param index   the index
	 * @param SVvalue the SV
	 */
	public void setSVbyIndex(final int index, final int SVvalue) {
		this.SV[index] = SVvalue;
	}
	
	/**
	 * @param index the index
	 * @return the SVH
	 */
	public int getSVHbyIndex(final int index) {
		return this.SVH[index];
	}
	
	/**
	 * @param index    the index
	 * @param SVHvalue the SVH
	 */
	public void setSVHbyIndex(final int index, final int SVHvalue) {
		this.SVH[index] = SVHvalue;
	}
	
	@Override
	public boolean equals(final Object o) {
		if (this == o) {
			return true;
		}
		if (!(o instanceof HEALTHObject)) {
			return false;
		}
		
		final HEALTHObject that = (HEALTHObject) o;
		
		if (this.data_id != that.data_id) {
			return false;
		}
		if (!Arrays.equals(this.SV, that.SV)) {
			return false;
		}
		if (!Arrays.equals(this.SVH, that.SVH)) {
			return false;
		}
		
		return true;
	}
	
	@Override
	public int hashCode() {
		int result = this.SV != null ? Arrays.hashCode(this.SV) : 0;
		result = (31 * result) + (this.SVH != null ? Arrays.hashCode(this.SVH) : 0);
		result = (31 * result) + this.data_id;
		return result;
	}
	
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		sb.append("HEALTHObject{data_id=");
		sb.append(this.data_id);
		for (int index = 1; index <= 32; index++) {
			sb.append(", SV");
			sb.append(index);
			sb.append("=");
			sb.append(this.SV[index - 1]);
		}
		for (int index = 0; index <= 7; index++) {
			sb.append(", SVH");
			sb.append(index + 25);
			sb.append("=");
			sb.append(this.SVH[index]);
		}
		sb.append("}");
		return sb.toString();
	}
	
} public class IONOObject implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "IONO";
	
	private double alpha0 = Double.NaN;
	
	private double alpha1 = Double.NaN;
	
	private double alpha2 = Double.NaN;
	
	private double alpha3 = Double.NaN;
	
	private double beta0 = Double.NaN;
	
	private double beta1 = Double.NaN;
	
	private double beta2 = Double.NaN;
	
	private double beta3 = Double.NaN;
	
	private double A0 = Double.NaN;
	
	private double A1 = Double.NaN;
	
	private double tot = Double.NaN;
	
	private int WNt = -1;
	
	private int leap = -1;
	
	private int WNlsf = -1;
	
	private int DN = -1;
	
	private int lsf = -1;
	
	/**
	 * @return the alpha0
	 */
	public double getAlpha0() {
		return this.alpha0;
	}
	
	/**
	 * @param alpha0 the alpha0 to set
	 */
	public void setAlpha0(final double alpha0) {
		this.alpha0 = alpha0;
	}
	
	/**
	 * @return the alpha1
	 */
	public double getAlpha1() {
		return this.alpha1;
	}
	
	/**
	 * @param alpha1 the alpha1 to set
	 */
	public void setAlpha1(final double alpha1) {
		this.alpha1 = alpha1;
	}
	
	/**
	 * @return the alpha2
	 */
	public double getAlpha2() {
		return this.alpha2;
	}
	
	/**
	 * @param alpha2 the alpha2 to set
	 */
	public void setAlpha2(final double alpha2) {
		this.alpha2 = alpha2;
	}
	
	/**
	 * @return the alpha3
	 */
	public double getAlpha3() {
		return this.alpha3;
	}
	
	/**
	 * @param alpha3 the alpha3 to set
	 */
	public void setAlpha3(final double alpha3) {
		this.alpha3 = alpha3;
	}
	
	/**
	 * @return the beta0
	 */
	public double getBeta0() {
		return this.beta0;
	}
	
	/**
	 * @param beta0 the beta0 to set
	 */
	public void setBeta0(final double beta0) {
		this.beta0 = beta0;
	}
	
	/**
	 * @return the beta1
	 */
	public double getBeta1() {
		return this.beta1;
	}
	
	/**
	 * @param beta1 the beta1 to set
	 */
	public void setBeta1(final double beta1) {
		this.beta1 = beta1;
	}
	
	/**
	 * @return the beta2
	 */
	public double getBeta2() {
		return this.beta2;
	}
	
	/**
	 * @param beta2 the beta2 to set
	 */
	public void setBeta2(final double beta2) {
		this.beta2 = beta2;
	}
	
	/**
	 * @return the beta3
	 */
	public double getBeta3() {
		return this.beta3;
	}
	
	/**
	 * @param beta3 the beta3 to set
	 */
	public void setBeta3(final double beta3) {
		this.beta3 = beta3;
	}
	
	/**
	 * @return the a0
	 */
	public double getA0() {
		return this.A0;
	}
	
	/**
	 * @param a0 the a0 to set
	 */
	public void setA0(final double a0) {
		this.A0 = a0;
	}
	
	/**
	 * @return the a1
	 */
	public double getA1() {
		return this.A1;
	}
	
	/**
	 * @param a1 the a1 to set
	 */
	public void setA1(final double a1) {
		this.A1 = a1;
	}
	
	/**
	 * @return the tot
	 */
	public double getTot() {
		return this.tot;
	}
	
	/**
	 * @param tot the tot to set
	 */
	public void setTot(final double tot) {
		this.tot = tot;
	}
	
	/**
	 * @return the wNt
	 */
	public int getWNt() {
		return this.WNt;
	}
	
	/**
	 * @param wNt the wNt to set
	 */
	public void setWNt(final int wNt) {
		this.WNt = wNt;
	}
	
	/**
	 * @return the leap
	 */
	public int getLeap() {
		return this.leap;
	}
	
	/**
	 * @param leap the leap to set
	 */
	public void setLeap(final int leap) {
		this.leap = leap;
	}
	
	/**
	 * @return the wNlsf
	 */
	public int getWNlsf() {
		return this.WNlsf;
	}
	
	/**
	 * @param wNlsf the wNlsf to set
	 */
	public void setWNlsf(final int wNlsf) {
		this.WNlsf = wNlsf;
	}
	
	/**
	 * @return the dN
	 */
	public int getDN() {
		return this.DN;
	}
	
	/**
	 * @param dN the dN to set
	 */
	public void setDN(final int dN) {
		this.DN = dN;
	}
	
	/**
	 * @return the lsf
	 */
	public int getLsf() {
		return this.lsf;
	}
	
	/**
	 * @param lsf the lsf to set
	 */
	public void setLsf(final int lsf) {
		this.lsf = lsf;
	}
	
	@Override
	public boolean equals(final Object o) {
		if (this == o) {
			return true;
		}
		if (!(o instanceof IONOObject)) {
			return false;
		}
		
		final IONOObject that = (IONOObject) o;
		
		if (Double.compare(that.A0, this.A0) != 0) {
			return false;
		}
		if (Double.compare(that.A1, this.A1) != 0) {
			return false;
		}
		if (this.DN != that.DN) {
			return false;
		}
		if (this.WNlsf != that.WNlsf) {
			return false;
		}
		if (this.WNt != that.WNt) {
			return false;
		}
		if (Double.compare(that.alpha0, this.alpha0) != 0) {
			return false;
		}
		if (Double.compare(that.alpha1, this.alpha1) != 0) {
			return false;
		}
		if (Double.compare(that.alpha2, this.alpha2) != 0) {
			return false;
		}
		if (Double.compare(that.alpha3, this.alpha3) != 0) {
			return false;
		}
		if (Double.compare(that.beta0, this.beta0) != 0) {
			return false;
		}
		if (Double.compare(that.beta1, this.beta1) != 0) {
			return false;
		}
		if (Double.compare(that.beta2, this.beta2) != 0) {
			return false;
		}
		if (Double.compare(that.beta3, this.beta3) != 0) {
			return false;
		}
		if (this.leap != that.leap) {
			return false;
		}
		if (this.lsf != that.lsf) {
			return false;
		}
		if (Double.compare(that.tot, this.tot) != 0) {
			return false;
		}
		
		return true;
	}
	
	@Override
	public int hashCode() {
		int result;
		long temp;
		temp = this.alpha0 != +0.0d ? Double.doubleToLongBits(this.alpha0) : 0L;
		result = (int) (temp ^ (temp >>> 32));
		temp = this.alpha1 != +0.0d ? Double.doubleToLongBits(this.alpha1) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.alpha2 != +0.0d ? Double.doubleToLongBits(this.alpha2) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.alpha3 != +0.0d ? Double.doubleToLongBits(this.alpha3) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.beta0 != +0.0d ? Double.doubleToLongBits(this.beta0) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.beta1 != +0.0d ? Double.doubleToLongBits(this.beta1) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.beta2 != +0.0d ? Double.doubleToLongBits(this.beta2) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.beta3 != +0.0d ? Double.doubleToLongBits(this.beta3) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.A0 != +0.0d ? Double.doubleToLongBits(this.A0) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.A1 != +0.0d ? Double.doubleToLongBits(this.A1) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		temp = this.tot != +0.0d ? Double.doubleToLongBits(this.tot) : 0L;
		result = (31 * result) + (int) (temp ^ (temp >>> 32));
		result = (31 * result) + this.WNt;
		result = (31 * result) + this.leap;
		result = (31 * result) + this.WNlsf;
		result = (31 * result) + this.DN;
		result = (31 * result) + this.lsf;
		return result;
	}
	
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		sb.append("IONOObject{alpha0=");
		sb.append(this.alpha0);
		sb.append(", alpha1=");
		sb.append(this.alpha1);
		sb.append(", alpha2=");
		sb.append(this.alpha2);
		sb.append(", alpha3=");
		sb.append(this.alpha3);
		sb.append(", beta0=");
		sb.append(this.beta0);
		sb.append(", beta1=");
		sb.append(this.beta1);
		sb.append(", beta2=");
		sb.append(this.beta2);
		sb.append(", beta3=");
		sb.append(this.beta3);
		sb.append(", A0=");
		sb.append(this.A0);
		sb.append(", A1=");
		sb.append(this.A1);
		sb.append(", tot=");
		sb.append(this.tot);
		sb.append(", WNt=");
		sb.append(this.WNt);
		sb.append(", leap=");
		sb.append(this.leap);
		sb.append(", WNlsf=");
		sb.append(this.WNlsf);
		sb.append(", DN=");
		sb.append(this.DN);
		sb.append(", lsf=");
		sb.append(this.lsf);
		sb.append("}");
		return sb.toString();
	}
	
} public class SUBFRAMEObject implements IGPSObject {
	
	/**
	 * the GPSd internal name
	 */
	public static final String NAME = "SUBFRAME";
	
	private String device = null;
	
	private int subframeNumber = -1;
	
	private int satelliteNumber = -1;
	
	private int MSBs = -1;
	
	private boolean scaled = false;
	
	private int pageid = -1;
	
	private String systemMessage = null;
	
	private ALMANACObject almanac;
	
	private EPHEM1Object ephem1;
	
	private EPHEM2Object ephem2;
	
	private EPHEM3Object ephem3;
	
	private ERDObject erd;
	
	private HEALTHObject health;
	
	private HEALTH2Object health2;
	
	private IONOObject iono;
	
	/**
	 * Name of originating device
	 *
	 * @return the device
	 */
	public String getDevice() {
		return this.device;
	}
	
	/**
	 * Name of originating device
	 *
	 * @param device the device to set
	 */
	public void setDevice(final String device) {
		this.device = device;
	}
	
	/**
	 * Subframe number
	 *
	 * @return the subframe number
	 */
	public int getSubFrameNumber() {
		return this.subframeNumber;
	}
	
	/**
	 * Subframe number
	 *
	 * @param subframeNumber to set
	 */
	public void setSubframeNumber(final int subframeNumber) {
		this.subframeNumber = subframeNumber;
	}
	
	/**
	 * Satellite number
	 *
	 * @return the satellite number
	 */
	public int getSatelliteNumber() {
		return this.satelliteNumber;
	}
	
	/**
	 * Satellite number
	 *
	 * @param satelliteNumber satellite number to set
	 */
	public void setSatelliteNumber(final int satelliteNumber) {
		this.satelliteNumber = satelliteNumber;
	}
	
	/**
	 * TOW17 field containing the 17 MSBs of the start of the next 12-second message
	 *
	 * @return TOW17
	 */
	public int getMSBs() {
		return this.MSBs;
	}
	
	/**
	 * TOW17 field containing the 17 MSBs of the start of the next 12-second message
	 *
	 * @param MSBs TOW17 to set
	 */
	public void setMSBs(final int MSBs) {
		this.MSBs = MSBs;
	}
	
	/**
	 * field telling whether the remainder of the fields are dumped in scaled or unscaled form
	 *
	 * @return scaled
	 */
	public boolean getScaled() {
		return this.scaled;
	}
	
	/**
	 * field telling whether the remainder of the fields are dumped in scaled or unscaled form
	 *
	 * @param scaled scaled to set
	 */
	public void setScaled(final boolean scaled) {
		this.scaled = scaled;
	}
	
	/**
	 * optional pageid for ERD, IONO, HEALTH and system message
	 *
	 * @return pageid
	 */
	public int getPageid() {
		return this.pageid;
	}
	
	/**
	 * optional pageid for ERD, IONO, HEALTH and system message
	 *
	 * @param pageid page id to set
	 */
	public void setPageid(final int pageid) {
		this.pageid = pageid;
	}
	
	/**
	 * optional system message
	 *
	 * @return system message
	 */
	public String getSystemMessage() {
		return this.systemMessage;
	}
	
	/**
	 * optional system message
	 *
	 * @param systemMessage system message to set
	 */
	public void setSystemMessage(final String systemMessage) {
		this.systemMessage = systemMessage;
	}
	
	/**
	 * Optional ALMANAC object
	 *
	 * @return ALMANAC
	 */
	public ALMANACObject getAlmanac() {
		return this.almanac;
	}
	
	/**
	 * Optional ALMANAC object
	 *
	 * @param almanac ALMANAC to set
	 */
	public void setAlmanac(final ALMANACObject almanac) {
		this.almanac = almanac;
	}
	
	/**
	 * Optional EPHEM1 object
	 *
	 * @return EPHEM1
	 */
	public EPHEM1Object getEphem1() {
		return this.ephem1;
	}
	
	/**
	 * Optional EPHEM1 object
	 *
	 * @param ephem1 EPHEM1 to set
	 */
	public void setEphem1(final EPHEM1Object ephem1) {
		this.ephem1 = ephem1;
	}
	
	/**
	 * Optional EPHEM2 object
	 *
	 * @return EPHEM2
	 */
	public EPHEM2Object getEphem2() {
		return this.ephem2;
	}
	
	/**
	 * Optional EPHEM2 object
	 *
	 * @param ephem2 EPHEM2 to set
	 */
	public void setEphem2(final EPHEM2Object ephem2) {
		this.ephem2 = ephem2;
	}
	
	/**
	 * Optional EPHEM3 object
	 *
	 * @return EPHEM3
	 */
	public EPHEM3Object getEphem3() {
		return this.ephem3;
	}
	
	/**
	 * Optional EPHEM3 object
	 *
	 * @param ephem3 EPHEM3 to set
	 */
	public void setEphem3(final EPHEM3Object ephem3) {
		this.ephem3 = ephem3;
	}
	
	/**
	 * Optional ERD object
	 *
	 * @return ERD
	 */
	public ERDObject getErd() {
		return this.erd;
	}
	
	/**
	 * Optional ERD object
	 *
	 * @param erd ERD to set
	 */
	public void setErd(final ERDObject erd) {
		this.erd = erd;
	}
	
	/**
	 * Optional HEALTH object
	 *
	 * @return HEALTH
	 */
	public HEALTHObject getHealth() {
		return this.health;
	}
	
	/**
	 * Optional HEALTH object
	 *
	 * @param health HEALTH to set
	 */
	public void setHealth(final HEALTHObject health) {
		this.health = health;
	}
	
	/**
	 * Optional HEALTH2 object
	 *
	 * @return HEALTH2
	 */
	public HEALTH2Object getHealth2() {
		return this.health2;
	}
	
	/**
	 * Optional HEALTH2 object
	 *
	 * @param health2 HEALTH2 to set
	 */
	public void setHealth2(final HEALTH2Object health2) {
		this.health2 = health2;
	}
	
	/**
	 * Optional IONO object
	 *
	 * @return IONO
	 */
	public IONOObject getIono() {
		return this.iono;
	}
	
	/**
	 * Optional IONO object
	 *
	 * @param iono IONO to set
	 */
	public void setIono(final IONOObject iono) {
		this.iono = iono;
	}
	
	@Override
	public boolean equals(final Object o) {
		if (this == o) {
			return true;
		}
		if (!(o instanceof SUBFRAMEObject)) {
			return false;
		}
		
		final SUBFRAMEObject that = (SUBFRAMEObject) o;
		
		if (this.MSBs != that.MSBs) {
			return false;
		}
		if (this.pageid != that.pageid) {
			return false;
		}
		if (this.satelliteNumber != that.satelliteNumber) {
			return false;
		}
		if (this.scaled != that.scaled) {
			return false;
		}
		if (this.subframeNumber != that.subframeNumber) {
			return false;
		}
		if (this.almanac != null ? !this.almanac.equals(that.almanac) : that.almanac != null) {
			return false;
		}
		if (this.device != null ? !this.device.equals(that.device) : that.device != null) {
			return false;
		}
		if (this.ephem1 != null ? !this.ephem1.equals(that.ephem1) : that.ephem1 != null) {
			return false;
		}
		if (this.ephem2 != null ? !this.ephem2.equals(that.ephem2) : that.ephem2 != null) {
			return false;
		}
		if (this.ephem3 != null ? !this.ephem3.equals(that.ephem3) : that.ephem3 != null) {
			return false;
		}
		if (this.erd != null ? !this.erd.equals(that.erd) : that.erd != null) {
			return false;
		}
		if (this.health != null ? !this.health.equals(that.health) : that.health != null) {
			return false;
		}
		if (this.health2 != null ? !this.health2.equals(that.health2) : that.health2 != null) {
			return false;
		}
		if (this.iono != null ? !this.iono.equals(that.iono) : that.iono != null) {
			return false;
		}
		if (this.systemMessage != null ? !this.systemMessage.equals(that.systemMessage) : that.systemMessage != null) {
			return false;
		}
		
		return true;
	}
	
	@Override
	public int hashCode() {
		int result = this.device != null ? this.device.hashCode() : 0;
		result = (31 * result) + this.subframeNumber;
		result = (31 * result) + this.satelliteNumber;
		result = (31 * result) + this.MSBs;
		result = (31 * result) + (this.scaled ? 1 : 0);
		result = (31 * result) + this.pageid;
		result = (31 * result) + (this.systemMessage != null ? this.systemMessage.hashCode() : 0);
		result = (31 * result) + (this.almanac != null ? this.almanac.hashCode() : 0);
		result = (31 * result) + (this.ephem1 != null ? this.ephem1.hashCode() : 0);
		result = (31 * result) + (this.ephem2 != null ? this.ephem2.hashCode() : 0);
		result = (31 * result) + (this.ephem3 != null ? this.ephem3.hashCode() : 0);
		result = (31 * result) + (this.erd != null ? this.erd.hashCode() : 0);
		result = (31 * result) + (this.health != null ? this.health.hashCode() : 0);
		result = (31 * result) + (this.health2 != null ? this.health2.hashCode() : 0);
		result = (31 * result) + (this.iono != null ? this.iono.hashCode() : 0);
		return result;
	}
	
	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		sb.append("SUBFRAMEObject{device=");
		sb.append(this.device);
		sb.append(", subframeNumber=");
		sb.append(this.subframeNumber);
		sb.append(", satelliteNumber=");
		sb.append(this.satelliteNumber);
		sb.append(", TOW17=");
		sb.append(this.MSBs);
		sb.append(", scaled=");
		sb.append(this.scaled);
		sb.append(", pageid=");
		sb.append(this.pageid);
		if (this.almanac != null) {
			sb.append(", almanac={");
			sb.append(this.almanac.toString());
			sb.append("}");
		} else if (this.ephem1 != null) {
			sb.append(", ephem1={");
			sb.append(this.ephem1.toString());
			sb.append("}");
		} else if (this.ephem2 != null) {
			sb.append(", ephem2={");
			sb.append(this.ephem2.toString());
			sb.append("}");
		} else if (this.ephem3 != null) {
			sb.append(", ephem3={");
			sb.append(this.ephem3.toString());
			sb.append("}");
		} else if (this.erd != null) {
			sb.append(", erd={");
			sb.append(this.erd.toString());
			sb.append("}");
		} else if (this.health != null) {
			sb.append(", health={");
			sb.append(this.health.toString());
			sb.append("}");
		} else if (this.health2 != null) {
			sb.append(", health2={");
			sb.append(this.health2.toString());
			sb.append("}");
		} else if (this.systemMessage != null) {
			sb.append(", systemMessage=");
			sb.append(this.systemMessage);
		} else if (this.iono != null) {
			sb.append(", iono={");
			sb.append(this.iono.toString());
			sb.append("}");
		}
		sb.append("}");
		return sb.toString();
	}
	
}
import java.util.Collections;
import org.json.JSONObject;
import de.taimos.gpsd4java.types.ATTObject;
import de.taimos.gpsd4java.types.DeviceObject;
import de.taimos.gpsd4java.types.DevicesObject;
import de.taimos.gpsd4java.types.ENMEAMode;
import de.taimos.gpsd4java.types.EParity;
import de.taimos.gpsd4java.types.GSTObject;
import de.taimos.gpsd4java.types.IGPSObject;
import de.taimos.gpsd4java.types.ParseException;
import de.taimos.gpsd4java.types.PollObject;
import de.taimos.gpsd4java.types.SATObject;
import de.taimos.gpsd4java.types.SKYObject;
import de.taimos.gpsd4java.types.TPVObject;
import de.taimos.gpsd4java.types.VersionObject;
import de.taimos.gpsd4java.types.WatchObject;
import de.taimos.gpsd4java.types.subframes.ALMANACObject;
import de.taimos.gpsd4java.types.subframes.EPHEM1Object;
import de.taimos.gpsd4java.types.subframes.EPHEM2Object;
import de.taimos.gpsd4java.types.subframes.EPHEM3Object;
import de.taimos.gpsd4java.types.subframes.ERDObject;
import de.taimos.gpsd4java.types.subframes.HEALTH2Object;
import de.taimos.gpsd4java.types.subframes.HEALTHObject;
import de.taimos.gpsd4java.types.subframes.IONOObject;
import de.taimos.gpsd4java.types.subframes.SUBFRAMEObject;
package de.taimos.gpsd4java.backend;

/*
 * #%L
 * GPSd4Java
 * %%
 * Copyright (C) 2011 - 2012 Taimos GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */




/**
 * This class is used to parse responses from GPSd<br>
 *
 * @author thoeger
 */
public class ResultParser extends AbstractResultParser {
	
	/**
	 * parse {@link JSONObject} into {@link IGPSObject}
	 *
	 * @param json the {@link JSONObject} to parse
	 * @return the parsed object
	 * @throws ParseException if parsing fails
	 */
	@Override
	public IGPSObject parse(final JSONObject json) throws ParseException {
		IGPSObject gps = null;
		final String clazz = json.optString("class");
		
		if (TPVObject.NAME.equals(clazz)) {
			gps = this.parseTPV(json);
		} else if (SKYObject.NAME.equals(clazz)) {
			gps = this.parseSKY(json);
		} else if (GSTObject.NAME.equals(clazz)) {
			gps = this.parseGST(json);
		} else if (ATTObject.NAME.equals(clazz)) {
			gps = this.parseATT(json);
		} else if (SUBFRAMEObject.NAME.equals(clazz)) {
			gps = this.parseSUBFRAME(json);
		} else if (VersionObject.NAME.equals(clazz)) {
			gps = this.parseVERSION(json);
		} else if (DevicesObject.NAME.equals(clazz)) {
			gps = this.parseDEVICES(json);
		} else if (DeviceObject.NAME.equals(clazz)) {
			gps = this.parseDEVICE(json);
		} else if (WatchObject.NAME.equals(clazz)) {