001/*
002 *  SI Units of Measurement for Java
003 *  Copyright (c) 2005-2017, Jean-Marie Dautelle, Werner Keil, V2COM.
004 *
005 * All rights reserved.
006 *
007 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
008 *
009 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
010 *
011 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
012 *
013 * 3. Neither the name of JSR-363 nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
014 *
015 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
016 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
017 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
018 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
019 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
020 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
021 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
022 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
023 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
024 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
025 */
026package si.uom;
027
028import static tec.uom.se.unit.MetricPrefix.CENTI;
029import static tec.uom.se.unit.Units.*;
030
031import javax.measure.Quantity;
032import javax.measure.Unit;
033import javax.measure.quantity.Acceleration;
034import javax.measure.quantity.AmountOfSubstance;
035import javax.measure.quantity.Angle;
036import javax.measure.quantity.Area;
037import javax.measure.quantity.Dimensionless;
038import javax.measure.quantity.ElectricCharge;
039import javax.measure.quantity.ElectricCurrent;
040import javax.measure.quantity.Energy;
041import javax.measure.quantity.Force;
042import javax.measure.quantity.Frequency;
043import javax.measure.quantity.Illuminance;
044import javax.measure.quantity.Length;
045import javax.measure.quantity.MagneticFlux;
046import javax.measure.quantity.MagneticFluxDensity;
047import javax.measure.quantity.Mass;
048import javax.measure.quantity.Power;
049import javax.measure.quantity.Pressure;
050import javax.measure.quantity.RadiationDoseAbsorbed;
051import javax.measure.quantity.RadiationDoseEffective;
052import javax.measure.quantity.Radioactivity;
053import javax.measure.quantity.SolidAngle;
054import javax.measure.quantity.Speed;
055import javax.measure.quantity.Temperature;
056import javax.measure.quantity.Time;
057
058import si.uom.quantity.DynamicViscosity;
059import si.uom.quantity.IonizingRadiation;
060import si.uom.quantity.KinematicViscosity;
061import tec.uom.se.AbstractSystemOfUnits;
062import tec.uom.se.AbstractUnit;
063import tec.uom.se.format.SimpleUnitFormat;
064import tec.uom.se.function.LogConverter;
065import tec.uom.se.function.MultiplyConverter;
066import tec.uom.se.function.PiMultiplierConverter;
067import tec.uom.se.function.RationalConverter;
068import tec.uom.se.unit.TransformedUnit;
069import tec.uom.se.unit.Units;
070
071/**
072 * <p>
073 * This class contains units that are not part of the International System of
074 * Units, that is, they are outside the SI, but are important and widely used.
075 * </p>
076 *
077 * <p>
078 * This class is not intended to be implemented by clients.
079 * </p>
080 * 
081 * @noimplement This class is not intended to be implemented by clients.
082 * @noextend This class is not intended to be extended by clients.
083 * 
084 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
085 * @author <a href="mailto:units@catmedia.us">Werner Keil</a>
086 * @version 1.0.3, $Date: 2017-02-12$
087 */
088public class NonSI extends AbstractSystemOfUnits {
089    private static final String SYSTEM_NAME = "Non-SI Units";
090
091    /**
092     * Holds the standard gravity constant: 9.80665 m/s² exact.
093     */
094    private static final int STANDARD_GRAVITY_DIVIDEND = 980665;
095
096    private static final int STANDARD_GRAVITY_DIVISOR = 100000;
097
098    /**
099     * Holds the avoirdupois pound: 0.45359237 kg exact
100     */
101    static final int AVOIRDUPOIS_POUND_DIVIDEND = 45359237;
102
103    static final int AVOIRDUPOIS_POUND_DIVISOR = 100000000;
104
105    /**
106     * Holds the Avogadro constant.
107     */
108    private static final double AVOGADRO_CONSTANT = 6.02214199e23; // (1/mol).
109
110    /**
111     * Holds the electric charge of one electron.
112     */
113    private static final double ELEMENTARY_CHARGE = 1.602176462e-19; // (C).
114
115    /**
116     * Default constructor (prevents this class from being instantiated).
117     */
118    private NonSI() {
119    }
120
121    /**
122     * Returns the unique instance of this class.
123     * 
124     * @return the NonSI instance.
125     */
126    public static NonSI getInstance() {
127        return INSTANCE;
128    }
129
130    private static final NonSI INSTANCE = new NonSI();
131
132    /////////////////////////////////////////////////////////////////
133    // Units outside the SI that are accepted for use with the SI. //
134    /////////////////////////////////////////////////////////////////
135
136    /**
137     * An angle unit accepted for use with SI units (standard name
138     * <code>deg</code>).
139     */
140    public static final Unit<Angle> DEGREE_ANGLE = addUnit(
141            new TransformedUnit<Angle>(RADIAN, new PiMultiplierConverter().concatenate(new RationalConverter(1, 180))),
142            "Degree Angle", "deg");
143
144    /**
145     * An angle unit accepted for use with SI units (standard name
146     * <code>'</code>).
147     */
148    public static final Unit<Angle> MINUTE_ANGLE = addUnit(new TransformedUnit<Angle>(RADIAN,
149            new PiMultiplierConverter().concatenate(new RationalConverter(1, 180 * 60))), "Minute Angle", "'");
150
151    /**
152     * An angle unit accepted for use with SI units (standard name
153     * <code>''</code>).
154     */
155    public static final Unit<Angle> SECOND_ANGLE = addUnit(
156            new TransformedUnit<Angle>(RADIAN,
157                    new PiMultiplierConverter().concatenate(new RationalConverter(1, 180 * 60 * 60))),
158            "Second Angle", "''");
159
160    /**
161     * A mass unit accepted for use with SI units (standard name
162     * <code>t</code>).
163     */
164    public static final Unit<Mass> TONNE = AbstractSystemOfUnits.Helper.addUnit(INSTANCE.units,
165            new TransformedUnit<Mass>(KILOGRAM, new RationalConverter(1000, 1)), "Tonne", "t");
166
167    /**
168     * An energy unit accepted for use with SI units (standard name
169     * <code>eV</code>). The electronvolt is the kinetic energy acquired by an
170     * electron passing through a potential difference of 1 V in vacuum. The
171     * value must be obtained by experiment, and is therefore not known exactly.
172     */
173    public static final Unit<Energy> ELECTRON_VOLT = addUnit(
174            new TransformedUnit<Energy>(JOULE, new MultiplyConverter(1.602176487E-19)), "Electron Volt", "eV");
175    // CODATA 2006 - http://physics.nist.gov/cuu/Constants/codata.pdf
176
177    /**
178     * A mass unit accepted for use with SI units (standard name
179     * <code>u</code>). The unified atomic mass unit is equal to 1/12 of the
180     * mass of an unbound atom of the nuclide 12C, at rest and in its ground
181     * state. The value must be obtained by experiment, and is therefore not
182     * known exactly.
183     */
184    public static final Unit<Mass> UNIFIED_ATOMIC_MASS = addUnit(
185            new TransformedUnit<Mass>(KILOGRAM, new MultiplyConverter(1.660538782E-27)), "Unified atomic mass", "u",
186            true);
187    // CODATA 2006 - http://physics.nist.gov/cuu/Constants/codata.pdf
188
189    /**
190     * A length unit accepted for use with SI units (standard name
191     * <code>UA</code>). The astronomical unit is a unit of length. Its value is
192     * such that, when used to describe the motion of bodies in the solar
193     * system, the heliocentric gravitation constant is (0.017 202 098 95)2
194     * ua3·d-2. The value must be obtained by experiment, and is therefore not
195     * known exactly.
196     */
197    public static final Unit<Length> ASTRONOMICAL_UNIT = addUnit(
198            new TransformedUnit<Length>(METRE, new MultiplyConverter(149597871000.0)), "Astronomical Unit", "UA");
199    // Best estimate source: http://maia.usno.navy.mil/NSFA/CBE.html
200
201    /**
202     * An angle unit accepted for use with SI units (standard name
203     * <code>ha</code>).
204     */
205    public static final Unit<Area> HECTARE = addUnit(
206            new TransformedUnit<Area>(SQUARE_METRE, new RationalConverter(10000, 1)), "Hectare", "ha");
207
208    // /////////////////
209    // Dimensionless //
210    // /////////////////
211    /**
212     * A dimensionless unit equals to <code>pi</code> (standard name
213     * <code>Ï€</code>).
214     */
215    public static final Unit<Dimensionless> PI = addUnit(AbstractUnit.ONE.multiply(StrictMath.PI));
216
217    /**
218     * A dimensionless unit equals to <code>0.01</code> (standard name
219     * <code>%</code>).
220     */
221    // static final Unit<Dimensionless> PERCENT = addUnit(ONE
222    // .divide(100));
223
224    /**
225     * A logarithmic unit used to describe a ratio (standard name
226     * <code>dB</code>).
227     */
228    static final Unit<Dimensionless> DECIBEL = AbstractUnit.ONE
229            .transform(new LogConverter(10).inverse().concatenate(RationalConverter.of(1d, 10d)));
230
231    // ///////////////////////
232    // Amount of substance //
233    // ///////////////////////
234    /**
235     * A unit of amount of substance equals to one atom (standard name
236     * <code>atom</code>).
237     */
238    public static final Unit<AmountOfSubstance> ATOM = addUnit(MOLE.divide(AVOGADRO_CONSTANT));
239
240    // //////////
241    // Length //
242    // //////////
243
244    /**
245     * A unit of length equal to <code>1E-10 m</code> (standard name
246     * <code>\u00C5ngstr\u00F6m</code>).
247     */
248    public static final Unit<Length> ANGSTROM = addUnit(METRE.divide(10000000000L));
249
250    /**
251     * A unit of length equal to the distance that light travels in one year
252     * through a vacuum (standard name <code>ly</code>).
253     */
254    static final Unit<Length> LIGHT_YEAR = addUnit(METRE.multiply(9.460528405e15));
255
256    /**
257     * A unit of length equal to the distance at which a star would appear to
258     * shift its position by one arcsecond over the course the time (about 3
259     * months) in which the Earth moves a distance of {@link #ASTRONOMICAL_UNIT}
260     * in the direction perpendicular to the direction to the star (standard
261     * name <code>pc</code>).
262     */
263    public static final Unit<Length> PARSEC = addUnit(METRE.multiply(30856770e9));
264
265    // ////////////
266    // Duration //
267    // ////////////
268
269    /**
270     * A unit of duration equal to the time required for a complete rotation of
271     * the earth in reference to any star or to the vernal equinox at the
272     * meridian, equal to 23 hours, 56 minutes, 4.09 seconds (standard name
273     * <code>day_sidereal</code>).
274     */
275    public static final Unit<Time> DAY_SIDEREAL = addUnit(SECOND.multiply(86164.09));
276
277    /**
278     * A unit of duration equal to 365 {@link #DAY} (standard name
279     * <code>year</code>).
280     */
281    public static final Unit<Time> YEAR_CALENDAR = addUnit(Units.DAY.multiply(365));
282
283    /**
284     * A unit of duration equal to one complete revolution of the earth about
285     * the sun, relative to the fixed stars, or 365 days, 6 hours, 9 minutes,
286     * 9.54 seconds (standard name <code>year_sidereal</code>).
287     */
288    public static final Unit<Time> YEAR_SIDEREAL = addUnit(SECOND.multiply(31558149.54));
289
290    /**
291     * The Julian year, as used in astronomy and other sciences, is a time unit
292     * defined as exactly 365.25 days. This is the normal meaning of the unit
293     * "year" (symbol "a" from the Latin annus, annata) used in various
294     * scientific contexts.
295     */
296    public static final Unit<Time> YEAR_JULIEN = addUnit(SECOND.multiply(31557600));
297
298    // ////////
299    // Mass //
300    // ////////
301    /**
302     * A unit of mass equal to 1/12 the mass of the carbon-12 atom (standard
303     * name <code>u</code>).
304     */
305    static final Unit<Mass> ATOMIC_MASS = addUnit(KILOGRAM.multiply(1e-3 / AVOGADRO_CONSTANT));
306
307    /**
308     * A unit of mass equal to the mass of the electron (standard name
309     * <code>me</code>).
310     */
311    static final Unit<Mass> ELECTRON_MASS = addUnit(KILOGRAM.multiply(9.10938188e-31));
312
313    /**
314     * A unit of mass equal to <code>453.59237 grams</code> (avoirdupois pound,
315     * standard name <code>lb</code>).
316     */
317    static final Unit<Mass> POUND = addUnit(
318            KILOGRAM.multiply(AVOIRDUPOIS_POUND_DIVIDEND).divide(AVOIRDUPOIS_POUND_DIVISOR));
319
320    // ///////////////////
321    // Electric charge //
322    // ///////////////////
323    /**
324     * A unit of electric charge equal to the charge on one electron (standard
325     * name <code>e</code>).
326     */
327    static final Unit<ElectricCharge> E = addUnit(COULOMB.multiply(ELEMENTARY_CHARGE));
328
329    /**
330     * A unit of electric charge equal to equal to the product of Avogadro's
331     * number (see {@link SI#MOLE}) and the charge (1 e) on a single electron
332     * (standard name <code>Fd</code>).
333     */
334    static final Unit<ElectricCharge> FARADAY = addUnit(COULOMB.multiply(ELEMENTARY_CHARGE * AVOGADRO_CONSTANT)); // e/mol
335
336    /**
337     * A unit of electric charge which exerts a force of one dyne on an equal
338     * charge at a distance of one centimeter (standard name <code>Fr</code>).
339     */
340    static final Unit<ElectricCharge> FRANKLIN = addUnit(COULOMB.multiply(3.3356e-10));
341
342    // ///////////////
343    // Temperature //
344    // ///////////////
345    /**
346     * A unit of temperature equal to <code>5/9 °K</code> (standard name
347     * <code>°R</code>).
348     */
349    static final Unit<Temperature> RANKINE = addUnit(KELVIN.multiply(5).divide(9));
350
351    // /////////
352    // Angle //
353    // /////////
354
355    /**
356     * A unit of angle equal to a full circle or <code>2<i>&pi;</i>
357     * {@link SI#RADIAN}</code> (standard name <code>rev</code>).
358     */
359    public static final Unit<Angle> REVOLUTION = addUnit(RADIAN.multiply(2).multiply(Math.PI).asType(Angle.class));
360    /**
361     * An angle unit accepted for use with SI units (standard name
362     * <code>rev</code>).
363     */
364    // public static final Unit<Angle> REVOLUTION = addUnit(
365    // new TransformedUnit<Angle>(RADIAN, new
366    // PiMultiplierConverter().concatenate(new RationalConverter(2, 1))));
367
368    // ////////////
369    // Velocity //
370    // ////////////
371    /**
372     * A unit of velocity relative to the speed of light (standard name
373     * <code>c</code>).
374     */
375    static final Unit<Speed> C = addUnit(METRE_PER_SECOND.multiply(299792458));
376
377    // ////////////////
378    // Acceleration //
379    // ////////////////
380    /**
381     * A unit of acceleration equal to the gravity at the earth's surface
382     * (standard name <code>grav</code>).
383     */
384    static final Unit<Acceleration> G = addUnit(
385            METRE_PER_SQUARE_SECOND.multiply(STANDARD_GRAVITY_DIVIDEND).divide(STANDARD_GRAVITY_DIVISOR));
386
387    // ////////
388    // Area //
389    // ////////
390    /**
391     * A unit of area equal to <code>100 m²</code> (standard name <code>a</code>
392     * ).
393     */
394    static final Unit<Area> ARE = addUnit(SQUARE_METRE.multiply(100));
395
396    // ////////////////////
397    // Electric current //
398    // ////////////////////
399    /**
400     * A unit of electric charge equal to the centimeter-gram-second
401     * electromagnetic unit of magnetomotive force, equal to <code>10/4
402     * &pi;ampere-turn</code> (standard name <code>Gi</code>).
403     */
404    static final Unit<ElectricCurrent> GILBERT = addUnit(
405            AMPERE.multiply(10).divide(4).multiply(PI).asType(ElectricCurrent.class));
406
407    // //////////
408    // Energy //
409    // //////////
410    /**
411     * A unit of energy equal to <code>1E-7 J</code> (standard name
412     * <code>erg</code>).
413     */
414    static final Unit<Energy> ERG = addUnit(JOULE.divide(10000000));
415
416    // ///////////////
417    // Illuminance //
418    // ///////////////
419    /**
420     * A unit of illuminance equal to <code>1E4 Lx</code> (standard name
421     * <code>La</code>).
422     */
423    static final Unit<Illuminance> LAMBERT = addUnit(LUX.multiply(10000));
424
425    // /////////////////
426    // Magnetic Flux //
427    // /////////////////
428    /**
429     * A unit of magnetic flux equal <code>1E-8 Wb</code> (standard name
430     * <code>Mx</code>).
431     */
432    static final Unit<MagneticFlux> MAXWELL = addUnit(WEBER.divide(100000000));
433
434    // /////////////////////////
435    // Magnetic Flux Density //
436    // /////////////////////////
437    /**
438     * A unit of magnetic flux density equal <code>1000 A/m</code> (standard
439     * name <code>G</code>).
440     */
441    static final Unit<MagneticFluxDensity> GAUSS = addUnit(TESLA.divide(10000));
442
443    // /////////
444    // Force //
445    // /////////
446    /**
447     * A unit of force equal to <code>1E-5 N</code> (standard name
448     * <code>dyn</code>).
449     */
450    static final Unit<Force> DYNE = addUnit(NEWTON.divide(100000));
451
452    /**
453     * A unit of force equal to <code>9.80665 N</code> (standard name
454     * <code>kgf</code>).
455     */
456    static final Unit<Force> KILOGRAM_FORCE = addUnit(
457            NEWTON.multiply(STANDARD_GRAVITY_DIVIDEND).divide(STANDARD_GRAVITY_DIVISOR));
458
459    /**
460     * A unit of force equal to <code>{@link #POUND}·{@link #G}</code>
461     * (standard name <code>lbf</code>).
462     */
463    static final Unit<Force> POUND_FORCE = addUnit(
464            NEWTON.multiply(1L * AVOIRDUPOIS_POUND_DIVIDEND * STANDARD_GRAVITY_DIVIDEND)
465                    .divide(1L * AVOIRDUPOIS_POUND_DIVISOR * STANDARD_GRAVITY_DIVISOR));
466
467    // /////////
468    // Power //
469    // /////////
470    /**
471     * A unit of power equal to the power required to raise a mass of 75
472     * kilograms at a velocity of 1 meter per second (metric, standard name
473     * <code>hp</code>).
474     */
475    static final Unit<Power> HORSEPOWER = addUnit(WATT.multiply(735.499));
476
477    // ////////////
478    // Pressure //
479    // ////////////
480    /**
481     * A unit of pressure equal to the average pressure of the Earth's
482     * atmosphere at sea level (standard name <code>atm</code>).
483     */
484    static final Unit<Pressure> ATMOSPHERE = addUnit(PASCAL.multiply(101325));
485
486    /**
487     * A unit of pressure equal to <code>100 kPa</code> (standard name
488     * <code>bar</code>).
489     */
490    public static final Unit<Pressure> BAR = addUnit(PASCAL.multiply(100000));
491
492    /**
493     * A unit of pressure equal to the pressure exerted at the Earth's surface
494     * by a column of mercury 1 millimeter high (standard name <code>mmHg</code>
495     * ).
496     */
497    public static final Unit<Pressure> MILLIMETRE_OF_MERCURY = addUnit(PASCAL.multiply(133.322));
498
499    /**
500     * A unit of pressure equal to the pressure exerted at the Earth's surface
501     * by a column of mercury 1 inch high (standard name <code>inHg</code>).
502     */
503    public static final Unit<Pressure> INCH_OF_MERCURY = addUnit(PASCAL.multiply(3386.388));
504
505    // ///////////////////////////
506    // Radiation dose absorbed //
507    // ///////////////////////////
508    /**
509     * A unit of radiation dose absorbed equal to a dose of 0.01 joule of energy
510     * per kilogram of mass (J/kg) (standard name <code>rd</code>).
511     */
512    public static final Unit<RadiationDoseAbsorbed> RAD = addUnit(GRAY.divide(100));
513
514    /**
515     * A unit of radiation dose effective equal to <code>0.01 Sv</code>
516     * (standard name <code>rem</code>).
517     */
518    public static final Unit<RadiationDoseEffective> REM = addUnit(SIEVERT.divide(100));
519
520    // ////////////////////////
521    // Radioactive activity //
522    // ////////////////////////
523    /**
524     * A unit of radioctive activity equal to the activity of a gram of radium
525     * (standard name <code>Ci</code>).
526     */
527    static final Unit<Radioactivity> CURIE = addUnit(BECQUEREL.multiply(37000000000L));
528
529    /**
530     * A unit of radioctive activity equal to 1 million radioactive
531     * disintegrations per second (standard name <code>Rd</code>).
532     */
533    static final Unit<Radioactivity> RUTHERFORD = addUnit(BECQUEREL.multiply(1000000));
534
535    // ///////////////
536    // Solid angle //
537    // ///////////////
538    /**
539     * A unit of solid angle equal to <code>4 <i>&pi;</i> steradians</code>
540     * (standard name <code>sphere</code>).
541     */
542    static final Unit<SolidAngle> SPHERE = addUnit(STERADIAN.multiply(4).multiply(PI).asType(SolidAngle.class));
543
544    // //////////
545    // Volume //
546    // //////////
547
548    // /////////////
549    // Viscosity //
550    // /////////////
551    /**
552     * A unit of dynamic viscosity equal to <code>1 g/(cm·s)</code> (cgs unit).
553     */
554    static final Unit<DynamicViscosity> POISE = addUnit(GRAM.divide(CENTI(METRE).multiply(SECOND)))
555            .asType(DynamicViscosity.class);
556
557    /**
558     * A unit of kinematic viscosity equal to <code>1 cm²/s</code> (cgs unit).
559     */
560    static final Unit<KinematicViscosity> STOKE = addUnit(CENTI(METRE).pow(2).divide(SECOND))
561            .asType(KinematicViscosity.class);
562
563    // /////////////
564    // Frequency //
565    // /////////////
566    /**
567     * A unit used to measure the frequency (rate) at which an imaging device
568     * produces unique consecutive images (standard name <code>fps</code>).
569     */
570    static final Unit<Frequency> FRAMES_PER_SECOND = addUnit(AbstractUnit.ONE.divide(SECOND)).asType(Frequency.class);
571
572    // //////////
573    // Others //
574    // //////////
575    /**
576     * A unit used to measure the ionizing ability of radiation (standard name
577     * <code>Roentgen</code>).
578     */
579    // static final Unit<IonizingRadiation> ROENTGEN = SI.ROENTGEN;
580
581    /**
582     * A unit used to measure the ionizing ability of radiation (standard name
583     * <code>Roentgen</code>).
584     */
585    @SuppressWarnings("unchecked")
586    public static final Unit<IonizingRadiation> ROENTGEN = (Unit<IonizingRadiation>) addUnit(
587            COULOMB.divide(KILOGRAM).multiply(2.58e-4), "Roentgen", "r", true);
588
589    public String getName() {
590        return SYSTEM_NAME;
591    }
592
593    /**
594     * Adds a new unit not mapped to any specified quantity type.
595     *
596     * @param unit
597     *            the unit being added.
598     * @return <code>unit</code>.
599     */
600    private static <U extends Unit<?>> U addUnit(U unit) {
601        INSTANCE.units.add(unit);
602        return unit;
603    }
604
605    /**
606     * Adds a new unit and maps it to the specified quantity type.
607     *
608     * @param unit
609     *            the unit being added.
610     * @param type
611     *            the quantity type.
612     * @return <code>unit</code>.
613     */
614    private static <U extends AbstractUnit<?>> U addUnit(U unit, Class<? extends Quantity<?>> type) {
615        INSTANCE.units.add(unit);
616        INSTANCE.quantityToUnit.put(type, unit);
617        return unit;
618    }
619
620    /**
621     * Adds a new unit not mapped to any specified quantity type and puts a text
622     * as symbol or label.
623     *
624     * @param unit
625     *            the unit being added.
626     * @param name
627     *            the string to use as name
628     * @param text
629     *            the string to use as label or symbol
630     * @param isLabel
631     *            if the string should be used as a label or not
632     * @return <code>unit</code>.
633     */
634    private static <U extends Unit<?>> U addUnit(U unit, String name, String text, boolean isLabel) {
635        if (isLabel) {
636            SimpleUnitFormat.getInstance().label(unit, text);
637        }
638        if (name != null && unit instanceof AbstractUnit) {
639            return Helper.addUnit(INSTANCE.units, unit, name);
640        } else {
641            INSTANCE.units.add(unit);
642        }
643        return unit;
644    }
645
646    /**
647     * Adds a new unit not mapped to any specified quantity type and puts a text
648     * as symbol or label.
649     *
650     * @param unit
651     *            the unit being added.
652     * @param name
653     *            the string to use as name
654     * @param text
655     *            the string to use as label
656     * @return <code>unit</code>.
657     */
658    private static <U extends Unit<?>> U addUnit(U unit, String name, String text) {
659        return addUnit(unit, name, text, true);
660    }
661}