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