001    /*
002     *  Copyright 2009-2013 Stephen Colebourne
003     *
004     *  Licensed under the Apache License, Version 2.0 (the "License");
005     *  you may not use this file except in compliance with the License.
006     *  You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     *  Unless required by applicable law or agreed to in writing, software
011     *  distributed under the License is distributed on an "AS IS" BASIS,
012     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     *  See the License for the specific language governing permissions and
014     *  limitations under the License.
015     */
016    package org.joda.money;
017    
018    import java.io.InvalidObjectException;
019    import java.io.ObjectInputStream;
020    import java.io.Serializable;
021    import java.math.BigDecimal;
022    import java.math.RoundingMode;
023    import java.util.Arrays;
024    import java.util.Iterator;
025    
026    import org.joda.convert.FromString;
027    import org.joda.convert.ToString;
028    
029    /**
030     * An amount of money with the standard decimal places defined by the currency.
031     * <p>
032     * This class represents a quantity of money, stored as a {@code BigDecimal} amount
033     * in a single {@link CurrencyUnit currency}.
034     * <p>
035     * Every currency has a certain standard number of decimal places.
036     * This is typically 2 (Euro, British Pound, US Dollar) but might be
037     * 0 (Japanese Yen), 1 (Vietnamese Dong) or 3 (Bahrain Dinar).
038     * The {@code Money} class is fixed to this number of decimal places.
039     * <p>
040     * For example, US dollars has a standard number of decimal places of 2.
041     * The major units are dollars. The minor units are cents, 100 to the dollar.
042     * This class does not allow calculations on fractions of a cent.
043     * <p>
044     * This class is immutable and thread-safe.
045     */
046    public final class Money implements BigMoneyProvider, Comparable<BigMoneyProvider>, Serializable {
047    
048        /**
049         * The serialisation version.
050         */
051        private static final long serialVersionUID = 1L;
052    
053        /**
054         * The money, not null.
055         */
056        private final BigMoney money;
057    
058        //-----------------------------------------------------------------------
059        /**
060         * Obtains an instance of {@code Money} from a {@code BigDecimal}.
061         * <p>
062         * This allows you to create an instance with a specific currency and amount.
063         * No rounding is performed on the amount, so it must have a scale compatible
064         * with the currency.
065         *
066         * @param currency  the currency, not null
067         * @param amount  the amount of money, not null
068         * @return the new instance, never null
069         * @throws ArithmeticException if the scale exceeds the currency scale
070         */
071        public static Money of(CurrencyUnit currency, BigDecimal amount) {
072            MoneyUtils.checkNotNull(currency, "Currency must not be null");
073            if (amount.scale() > currency.getDecimalPlaces()) {
074                throw new ArithmeticException("Scale of amount " + amount + " is greater than the scale of the currency " + currency);
075            }
076            return Money.of(currency, amount, RoundingMode.UNNECESSARY);
077        }
078    
079        /**
080         * Obtains an instance of {@code Money} from a {@code BigDecimal}, rounding as necessary.
081         * <p>
082         * This allows you to create an instance with a specific currency and amount.
083         * If the amount has a scale in excess of the scale of the currency then the excess
084         * fractional digits are rounded using the rounding mode.
085         *
086         * @param currency  the currency, not null
087         * @param amount  the amount of money, not null
088         * @param roundingMode  the rounding mode to use, not null
089         * @return the new instance, never null
090         * @throws ArithmeticException if the rounding fails
091         */
092        public static Money of(CurrencyUnit currency, BigDecimal amount, RoundingMode roundingMode) {
093            MoneyUtils.checkNotNull(currency, "CurrencyUnit must not be null");
094            MoneyUtils.checkNotNull(amount, "Amount must not be null");
095            MoneyUtils.checkNotNull(roundingMode, "RoundingMode must not be null");
096            amount = amount.setScale(currency.getDecimalPlaces(), roundingMode);
097            return new Money(BigMoney.of(currency, amount));
098        }
099    
100        //-----------------------------------------------------------------------
101        /**
102         * Obtains an instance of {@code Money} from a {@code double} using a
103         * well-defined conversion.
104         * <p>
105         * This allows you to create an instance with a specific currency and amount.
106         * No rounding is performed on the amount, so it must have a scale compatible
107         * with the currency.
108         * <p>
109         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
110         * the most expected answer for most programming scenarios.
111         * Any {@code double} literal in code will be converted to
112         * exactly the same BigDecimal with the same scale.
113         * For example, the literal '1.45d' will be converted to '1.45'.
114         *
115         * @param currency  the currency, not null
116         * @param amount  the amount of money, not null
117         * @return the new instance, never null
118         * @throws ArithmeticException if the scale exceeds the currency scale
119         */
120        public static Money of(CurrencyUnit currency, double amount) {
121            return Money.of(currency, BigDecimal.valueOf(amount));
122        }
123    
124        /**
125         * Obtains an instance of {@code Money} from a {@code double} using a
126         * well-defined conversion, rounding as necessary.
127         * <p>
128         * This allows you to create an instance with a specific currency and amount.
129         * If the amount has a scale in excess of the scale of the currency then the excess
130         * fractional digits are rounded using the rounding mode.
131         * <p>
132         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
133         * the most expected answer for most programming scenarios.
134         * Any {@code double} literal in code will be converted to
135         * exactly the same BigDecimal with the same scale.
136         * For example, the literal '1.45d' will be converted to '1.45'.
137         *
138         * @param currency  the currency, not null
139         * @param amount  the amount of money, not null
140         * @param roundingMode  the rounding mode to use, not null
141         * @return the new instance, never null
142         * @throws ArithmeticException if the rounding fails
143         */
144        public static Money of(CurrencyUnit currency, double amount, RoundingMode roundingMode) {
145            return Money.of(currency, BigDecimal.valueOf(amount), roundingMode);
146        }
147    
148        //-----------------------------------------------------------------------
149        /**
150         * Obtains an instance of {@code Money} from an amount in major units.
151         * <p>
152         * This allows you to create an instance with a specific currency and amount.
153         * The amount is a whole number only. Thus you can initialise the value
154         * 'USD 20', but not the value 'USD 20.32'.
155         * For example, {@code ofMajor(USD, 25)} creates the instance {@code USD 25.00}.
156         *
157         * @param currency  the currency, not null
158         * @param amountMajor  the amount of money in the major division of the currency
159         * @return the new instance, never null
160         */
161        public static Money ofMajor(CurrencyUnit currency, long amountMajor) {
162            return Money.of(currency, BigDecimal.valueOf(amountMajor), RoundingMode.UNNECESSARY);
163        }
164    
165        /**
166         * Obtains an instance of {@code Money} from an amount in minor units.
167         * <p>
168         * This allows you to create an instance with a specific currency and amount
169         * expressed in terms of the minor unit.
170         * For example, if constructing US Dollars, the input to this method represents cents.
171         * Note that when a currency has zero decimal places, the major and minor units are the same.
172         * For example, {@code ofMajor(USD, 2595)} creates the instance {@code USD 25.95}.
173         *
174         * @param currency  the currency, not null
175         * @param amountMinor  the amount of money in the minor division of the currency
176         * @return the new instance, never null
177         */
178        public static Money ofMinor(CurrencyUnit currency, long amountMinor) {
179            return new Money(BigMoney.ofMinor(currency, amountMinor));
180        }
181    
182        //-----------------------------------------------------------------------
183        /**
184         * Obtains an instance of {@code Money} representing zero.
185         * <p>
186         * For example, {@code zero(USD)} creates the instance {@code USD 0.00}.
187         *
188         * @param currency  the currency, not null
189         * @return the instance representing zero, never null
190         */
191        public static Money zero(CurrencyUnit currency) {
192            MoneyUtils.checkNotNull(currency, "Currency must not be null");
193            BigDecimal bd = BigDecimal.valueOf(0, currency.getDecimalPlaces());
194            return new Money(BigMoney.of(currency, bd));
195        }
196    
197        //-----------------------------------------------------------------------
198        /**
199         * Obtains an instance of {@code Money} from a provider.
200         * <p>
201         * This allows you to create an instance from any class that implements the
202         * provider, such as {@code BigMoney}.
203         * No rounding is performed on the amount, so it must have a scale compatible
204         * with the currency.
205         *
206         * @param moneyProvider  the money to convert, not null
207         * @return the new instance, never null
208         * @throws ArithmeticException if the scale exceeds the currency scale
209         */
210        public static Money of(BigMoneyProvider moneyProvider) {
211            return Money.of(moneyProvider, RoundingMode.UNNECESSARY);
212        }
213    
214        /**
215         * Obtains an instance of {@code Money} from a provider, rounding as necessary.
216         * <p>
217         * This allows you to create an instance from any class that implements the
218         * provider, such as {@code BigMoney}.
219         * The rounding mode is used to adjust the scale to the scale of the currency.
220         *
221         * @param moneyProvider  the money to convert, not null
222         * @param roundingMode  the rounding mode to use, not null
223         * @return the new instance, never null
224         * @throws ArithmeticException if the rounding fails
225         */
226        public static Money of(BigMoneyProvider moneyProvider, RoundingMode roundingMode) {
227            MoneyUtils.checkNotNull(moneyProvider, "BigMoneyProvider must not be null");
228            MoneyUtils.checkNotNull(roundingMode, "RoundingMode must not be null");
229            return new Money(BigMoney.of(moneyProvider).withCurrencyScale(roundingMode));
230        }
231    
232        //-----------------------------------------------------------------------
233        /**
234         * Obtains an instance of {@code Money} as the total value of an array.
235         * <p>
236         * The array must contain at least one monetary value.
237         * Subsequent amounts are added as though using {@link #plus(Money)}.
238         * All amounts must be in the same currency.
239         * 
240         * @param monies  the monetary values to total, not empty, no null elements, not null
241         * @return the total, never null
242         * @throws IllegalArgumentException if the array is empty
243         * @throws CurrencyMismatchException if the currencies differ
244         */
245        public static Money total(Money... monies) {
246            MoneyUtils.checkNotNull(monies, "Money array must not be null");
247            if (monies.length == 0) {
248                throw new IllegalArgumentException("Money array must not be empty");
249            }
250            Money total = monies[0];
251            MoneyUtils.checkNotNull(total, "Money arary must not contain null entries");
252            for (int i = 1; i < monies.length; i++) {
253                total = total.plus(monies[i]);
254            }
255            return total;
256        }
257    
258        /**
259         * Obtains an instance of {@code Money} as the total value of a collection.
260         * <p>
261         * The iterable must provide at least one monetary value.
262         * Subsequent amounts are added as though using {@link #plus(Money)}.
263         * All amounts must be in the same currency.
264         * 
265         * @param monies  the monetary values to total, not empty, no null elements, not null
266         * @return the total, never null
267         * @throws IllegalArgumentException if the iterable is empty
268         * @throws CurrencyMismatchException if the currencies differ
269         */
270        public static Money total(Iterable<Money> monies) {
271            MoneyUtils.checkNotNull(monies, "Money iterator must not be null");
272            Iterator<Money> it = monies.iterator();
273            if (it.hasNext() == false) {
274                throw new IllegalArgumentException("Money iterator must not be empty");
275            }
276            Money total = it.next();
277            MoneyUtils.checkNotNull(total, "Money iterator must not contain null entries");
278            while (it.hasNext()) {
279                total = total.plus(it.next());
280            }
281            return total;
282        }
283    
284        /**
285         * Obtains an instance of {@code Money} as the total value of
286         * a possibly empty array.
287         * <p>
288         * The amounts are added as though using {@link #plus(Money)} starting
289         * from zero in the specified currency.
290         * All amounts must be in the same currency.
291         * 
292         * @param currency  the currency to total in, not null
293         * @param monies  the monetary values to total, no null elements, not null
294         * @return the total, never null
295         * @throws CurrencyMismatchException if the currencies differ
296         */
297        public static Money total(CurrencyUnit currency, Money... monies) {
298            return Money.zero(currency).plus(Arrays.asList(monies));
299        }
300    
301        /**
302         * Obtains an instance of {@code Money} as the total value of
303         * a possibly empty collection.
304         * <p>
305         * The amounts are added as though using {@link #plus(Money)} starting
306         * from zero in the specified currency.
307         * All amounts must be in the same currency.
308         * 
309         * @param currency  the currency to total in, not null
310         * @param monies  the monetary values to total, no null elements, not null
311         * @return the total, never null
312         * @throws CurrencyMismatchException if the currencies differ
313         */
314        public static Money total(CurrencyUnit currency, Iterable<Money> monies) {
315            return Money.zero(currency).plus(monies);
316        }
317    
318        //-----------------------------------------------------------------------
319        /**
320         * Parses an instance of {@code Money} from a string.
321         * <p>
322         * The string format is '<currencyCode> <amount>'.
323         * The currency code must be a valid three letter currency.
324         * The amount must match the regular expression {@code [+-]?[0-9]*[.]?[0-9]*}.
325         * This matches the output from {@link #toString()}.
326         * <p>
327         * For example, {@code of("USD 25")} creates the instance {@code USD 25.00}
328         * while {@code of("USD 25.95")} creates the instance {@code USD 25.95}.
329         *
330         * @param moneyStr  the money string to parse, not null
331         * @return the parsed instance, never null
332         * @throws IllegalArgumentException if the string is malformed
333         * @throws ArithmeticException if the amount is too large
334         */
335        @FromString
336        public static Money parse(String moneyStr) {
337            return Money.of(BigMoney.parse(moneyStr));
338        }
339    
340        //-----------------------------------------------------------------------
341        /**
342         * Ensures that a {@code Money} is not {@code null}.
343         * <p>
344         * If the input money is not {@code null}, then it is returned, providing
345         * that the currency matches the specified currency.
346         * If the input money is {@code null}, then zero money in the currency is returned.
347         * 
348         * @param money  the monetary value to check, may be null
349         * @param currency  the currency to use, not null
350         * @return the input money or zero in the specified currency, never null
351         * @throws CurrencyMismatchException if the input money is non-null and the currencies differ
352         */
353        public static Money nonNull(Money money, CurrencyUnit currency) {
354            if (money == null) {
355                return zero(currency);
356            }
357            if (money.getCurrencyUnit().equals(currency) == false) {
358                MoneyUtils.checkNotNull(currency, "Currency must not be null");
359                throw new CurrencyMismatchException(money.getCurrencyUnit(), currency);
360            }
361            return money;
362        }
363    
364        //-----------------------------------------------------------------------
365        /**
366         * Constructor, creating a new monetary instance.
367         * 
368         * @param money  the underlying money, not null
369         */
370        Money(BigMoney money) {
371            assert money != null : "Joda-Money bug: BigMoney must not be null";
372            assert money.isCurrencyScale() : "Joda-Money bug: Only currency scale is valid for Money";
373            this.money = money;
374        }
375    
376        /**
377         * Block malicious data streams.
378         * 
379         * @param ois  the input stream, not null
380         * @throws InvalidObjectException
381         */
382        private void readObject(ObjectInputStream ois) throws InvalidObjectException {
383            throw new InvalidObjectException("Serialization delegate required");
384        }
385    
386        /**
387         * Uses a serialization delegate.
388         * 
389         * @return the replacing object, never null
390         */
391        private Object writeReplace() {
392            return new Ser(Ser.MONEY, this);
393        }
394    
395        //-----------------------------------------------------------------------
396        /**
397         * Returns a new {@code Money}, returning {@code this} if possible.
398         * <p>
399         * This instance is immutable and unaffected by this method.
400         * 
401         * @param newInstance  the new money to use, not null
402         * @return the new instance, never null
403         */
404        private Money with(BigMoney newInstance) {
405            if (money.equals(newInstance)) {
406                return this;
407            }
408            return new Money(newInstance);
409        }
410    
411        //-----------------------------------------------------------------------
412        /**
413         * Gets the currency.
414         * 
415         * @return the currency, never null
416         */
417        public CurrencyUnit getCurrencyUnit() {
418            return money.getCurrencyUnit();
419        }
420    
421        //-----------------------------------------------------------------------
422        /**
423         * Returns a copy of this monetary value with the specified currency.
424         * <p>
425         * The returned instance will have the specified currency and the amount
426         * from this instance. If the scale differs between the currencies such
427         * that rounding would be required, then an exception is thrown.
428         * <p>
429         * This instance is immutable and unaffected by this method.
430         * 
431         * @param currency  the currency to use, not null
432         * @return the new instance with the input currency set, never null
433         * @throws ArithmeticException if the scale of the new currency is less than
434         *  the scale of this currency
435         */
436        public Money withCurrencyUnit(CurrencyUnit currency) {
437            return withCurrencyUnit(currency, RoundingMode.UNNECESSARY);
438        }
439    
440        /**
441         * Returns a copy of this monetary value with the specified currency.
442         * <p>
443         * The returned instance will have the specified currency and the amount
444         * from this instance. If the number of decimal places differs between the
445         * currencies, then the amount may be rounded.
446         * <p>
447         * This instance is immutable and unaffected by this method.
448         * 
449         * @param currency  the currency to use, not null
450         * @param roundingMode  the rounding mode to use to bring the decimal places back in line, not null
451         * @return the new instance with the input currency set, never null
452         * @throws ArithmeticException if the rounding fails
453         */
454        public Money withCurrencyUnit(CurrencyUnit currency, RoundingMode roundingMode) {
455            return with(money.withCurrencyUnit(currency).withCurrencyScale(roundingMode));
456        }
457    
458        //-----------------------------------------------------------------------
459        /**
460         * Gets the scale of the {@code BigDecimal} amount.
461         * <p>
462         * The scale has the same meaning as in {@link BigDecimal}.
463         * Positive values represent the number of decimal places in use.
464         * For example, a scale of 2 means that the money will have two decimal places
465         * such as 'USD 43.25'.
466         * <p>
467         * For {@code Money}, the scale is fixed and always matches that of the currency.
468         * 
469         * @return the scale in use, typically 2 but could be 0, 1 and 3
470         */
471        public int getScale() {
472            return money.getScale();
473        }
474    
475        //-----------------------------------------------------------------------
476        /**
477         * Gets the amount.
478         * <p>
479         * This returns the value of the money as a {@code BigDecimal}.
480         * The scale will be the scale of this money.
481         * 
482         * @return the amount, never null
483         */
484        public BigDecimal getAmount() {
485            return money.getAmount();
486        }
487    
488        /**
489         * Gets the amount in major units as a {@code BigDecimal} with scale 0.
490         * <p>
491         * This returns the monetary amount in terms of the major units of the currency,
492         * truncating the amount if necessary.
493         * For example, 'EUR 2.35' will return 2, and 'BHD -1.345' will return -1.
494         * <p>
495         * This is returned as a {@code BigDecimal} rather than a {@code BigInteger}.
496         * This is to allow further calculations to be performed on the result.
497         * Should you need a {@code BigInteger}, simply call {@link BigDecimal#toBigInteger()}.
498         * 
499         * @return the major units part of the amount, never null
500         */
501        public BigDecimal getAmountMajor() {
502            return money.getAmountMajor();
503        }
504    
505        /**
506         * Gets the amount in major units as a {@code long}.
507         * <p>
508         * This returns the monetary amount in terms of the major units of the currency,
509         * truncating the amount if necessary.
510         * For example, 'EUR 2.35' will return 2, and 'BHD -1.345' will return -1.
511         * 
512         * @return the major units part of the amount
513         * @throws ArithmeticException if the amount is too large for a {@code long}
514         */
515        public long getAmountMajorLong() {
516            return money.getAmountMajorLong();
517        }
518    
519        /**
520         * Gets the amount in major units as an {@code int}.
521         * <p>
522         * This returns the monetary amount in terms of the major units of the currency,
523         * truncating the amount if necessary.
524         * For example, 'EUR 2.35' will return 2, and 'BHD -1.345' will return -1.
525         * 
526         * @return the major units part of the amount
527         * @throws ArithmeticException if the amount is too large for an {@code int}
528         */
529        public int getAmountMajorInt() {
530            return money.getAmountMajorInt();
531        }
532    
533        /**
534         * Gets the amount in minor units as a {@code BigDecimal} with scale 0.
535         * <p>
536         * This returns the monetary amount in terms of the minor units of the currency,
537         * truncating the amount if necessary.
538         * For example, 'EUR 2.35' will return 235, and 'BHD -1.345' will return -1345.
539         * <p>
540         * This is returned as a {@code BigDecimal} rather than a {@code BigInteger}.
541         * This is to allow further calculations to be performed on the result.
542         * Should you need a {@code BigInteger}, simply call {@link BigDecimal#toBigInteger()}.
543         * 
544         * @return the minor units part of the amount, never null
545         */
546        public BigDecimal getAmountMinor() {
547            return money.getAmountMinor();
548        }
549    
550        /**
551         * Gets the amount in minor units as a {@code long}.
552         * <p>
553         * This returns the monetary amount in terms of the minor units of the currency,
554         * truncating the amount if necessary.
555         * For example, 'EUR 2.35' will return 235, and 'BHD -1.345' will return -1345.
556         * 
557         * @return the minor units part of the amount
558         * @throws ArithmeticException if the amount is too large for a {@code long}
559         */
560        public long getAmountMinorLong() {
561            return money.getAmountMinorLong();
562        }
563    
564        /**
565         * Gets the amount in minor units as an {@code int}.
566         * <p>
567         * This returns the monetary amount in terms of the minor units of the currency,
568         * truncating the amount if necessary.
569         * For example, 'EUR 2.35' will return 235, and 'BHD -1.345' will return -1345.
570         * 
571         * @return the minor units part of the amount
572         * @throws ArithmeticException if the amount is too large for an {@code int}
573         */
574        public int getAmountMinorInt() {
575            return money.getAmountMinorInt();
576        }
577    
578        /**
579         * Gets the minor part of the amount.
580         * <p>
581         * This return the minor unit part of the monetary amount.
582         * This is defined as the amount in minor units excluding major units.
583         * <p>
584         * For example, EUR has a scale of 2, so the minor part is always between 0 and 99
585         * for positive amounts, and 0 and -99 for negative amounts.
586         * Thus 'EUR 2.35' will return 35, and 'EUR -1.34' will return -34.
587         * 
588         * @return the minor part of the amount, negative if the amount is negative
589         */
590        public int getMinorPart() {
591            return money.getMinorPart();
592        }
593    
594        //-----------------------------------------------------------------------
595        /**
596         * Checks if the amount is zero.
597         * 
598         * @return true if the amount is zero
599         */
600        public boolean isZero() {
601            return money.isZero();
602        }
603    
604        /**
605         * Checks if the amount is greater than zero.
606         * 
607         * @return true if the amount is greater than zero
608         */
609        public boolean isPositive() {
610            return money.isPositive();
611        }
612    
613        /**
614         * Checks if the amount is zero or greater.
615         * 
616         * @return true if the amount is zero or greater
617         */
618        public boolean isPositiveOrZero() {
619            return money.isPositiveOrZero();
620        }
621    
622        /**
623         * Checks if the amount is less than zero.
624         * 
625         * @return true if the amount is less than zero
626         */
627        public boolean isNegative() {
628            return money.isNegative();
629        }
630    
631        /**
632         * Checks if the amount is zero or less.
633         * 
634         * @return true if the amount is zero or less
635         */
636        public boolean isNegativeOrZero() {
637            return money.isNegativeOrZero();
638        }
639    
640        //-----------------------------------------------------------------------
641        /**
642         * Returns a copy of this monetary value with the specified amount.
643         * <p>
644         * The returned instance will have this currency and the new amount.
645         * No rounding is performed on the amount to be added, so it must have a
646         * scale compatible with the currency.
647         * <p>
648         * This instance is immutable and unaffected by this method.
649         * 
650         * @param amount  the monetary amount to set in the returned instance, not null
651         * @return the new instance with the input amount set, never null
652         * @throws ArithmeticException if the scale of the amount is too large
653         */
654        public Money withAmount(BigDecimal amount) {
655            return withAmount(amount, RoundingMode.UNNECESSARY);
656        }
657    
658        /**
659         * Returns a copy of this monetary value with the specified amount.
660         * <p>
661         * The returned instance will have this currency and the new amount.
662         * If the scale of the {@code BigDecimal} needs to be adjusted, then
663         * it will be rounded using the specified mode.
664         * <p>
665         * This instance is immutable and unaffected by this method.
666         * 
667         * @param amount  the monetary amount to set in the returned instance, not null
668         * @param roundingMode  the rounding mode to adjust the scale, not null
669         * @return the new instance with the input amount set, never null
670         */
671        public Money withAmount(BigDecimal amount, RoundingMode roundingMode) {
672            return with(money.withAmount(amount).withCurrencyScale(roundingMode));
673        }
674    
675        /**
676         * Returns a copy of this monetary value with the specified amount using a well-defined
677         * conversion from a {@code double}.
678         * <p>
679         * The returned instance will have this currency and the new amount.
680         * No rounding is performed on the amount to be added, so it must have a
681         * scale compatible with the currency.
682         * <p>
683         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
684         * the most expected answer for most programming scenarios.
685         * Any {@code double} literal in code will be converted to
686         * exactly the same BigDecimal with the same scale.
687         * For example, the literal '1.45d' will be converted to '1.45'.
688         * <p>
689         * This instance is immutable and unaffected by this method.
690         * 
691         * @param amount  the monetary amount to set in the returned instance, not null
692         * @return the new instance with the input amount set, never null
693         * @throws ArithmeticException if the scale of the amount is too large
694         */
695        public Money withAmount(double amount) {
696            return withAmount(amount, RoundingMode.UNNECESSARY);
697        }
698    
699        /**
700         * Returns a copy of this monetary value with the specified amount using a well-defined
701         * conversion from a {@code double}.
702         * <p>
703         * The returned instance will have this currency and the new amount.
704         * If the scale of the {@code BigDecimal} needs to be adjusted, then
705         * it will be rounded using the specified mode.
706         * <p>
707         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
708         * the most expected answer for most programming scenarios.
709         * Any {@code double} literal in code will be converted to
710         * exactly the same BigDecimal with the same scale.
711         * For example, the literal '1.45d' will be converted to '1.45'.
712         * <p>
713         * This instance is immutable and unaffected by this method.
714         * 
715         * @param amount  the monetary amount to set in the returned instance, not null
716         * @param roundingMode  the rounding mode to adjust the scale, not null
717         * @return the new instance with the input amount set, never null
718         */
719        public Money withAmount(double amount, RoundingMode roundingMode) {
720            return with(money.withAmount(amount).withCurrencyScale(roundingMode));
721        }
722    
723        //-----------------------------------------------------------------------
724        /**
725         * Returns a copy of this monetary value with a collection of monetary amounts added.
726         * <p>
727         * This adds the specified amounts to this monetary amount, returning a new object.
728         * The amounts must be in the same currency.
729         * <p>
730         * This instance is immutable and unaffected by this method.
731         * 
732         * @param moniesToAdd  the monetary values to add, no null elements, not null
733         * @return the new instance with the input amounts added, never null
734         * @throws CurrencyMismatchException if the currencies differ
735         */
736        public Money plus(Iterable<Money> moniesToAdd) {
737            return with(money.plus(moniesToAdd));
738        }
739    
740        //-----------------------------------------------------------------------
741        /**
742         * Returns a copy of this monetary value with the amount added.
743         * <p>
744         * This adds the specified amount to this monetary amount, returning a new object.
745         * The amount added must be in the same currency.
746         * <p>
747         * The addition has no rounding issues and is always accurate.
748         * For example,'USD 25.95' plus 'USD 3.02' will 'USD 28.97'.
749         * <p>
750         * This instance is immutable and unaffected by this method.
751         * 
752         * @param moneyToAdd  the monetary value to add, not null
753         * @return the new instance with the input amount added, never null
754         * @throws CurrencyMismatchException if the currencies differ
755         */
756        public Money plus(Money moneyToAdd) {
757            return with(money.plus(moneyToAdd));
758        }
759    
760        /**
761         * Returns a copy of this monetary value with the amount added.
762         * <p>
763         * This adds the specified amount to this monetary amount, returning a new object.
764         * No rounding is performed on the amount to be added, so it must have a
765         * scale compatible with the currency.
766         * <p>
767         * This instance is immutable and unaffected by this method.
768         * 
769         * @param amountToAdd  the monetary value to add, not null
770         * @return the new instance with the input amount added, never null
771         * @throws ArithmeticException if the scale of the amount is too large
772         */
773        public Money plus(BigDecimal amountToAdd) {
774            return plus(amountToAdd, RoundingMode.UNNECESSARY);
775        }
776    
777        /**
778         * Returns a copy of this monetary value with the amount added.
779         * <p>
780         * This adds the specified amount to this monetary amount, returning a new object.
781         * If the amount to add exceeds the scale of the currency, then the
782         * rounding mode will be used to adjust the result.
783         * <p>
784         * This instance is immutable and unaffected by this method.
785         * 
786         * @param amountToAdd  the monetary value to add, not null
787         * @param roundingMode  the rounding mode to use, not null
788         * @return the new instance with the input amount added, never null
789         */
790        public Money plus(BigDecimal amountToAdd, RoundingMode roundingMode) {
791            return with(money.plusRetainScale(amountToAdd, roundingMode));
792        }
793    
794        /**
795         * Returns a copy of this monetary value with the amount added.
796         * <p>
797         * This adds the specified amount to this monetary amount, returning a new object.
798         * No rounding is performed on the amount to be added, so it must have a
799         * scale compatible with the currency.
800         * <p>
801         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
802         * the most expected answer for most programming scenarios.
803         * Any {@code double} literal in code will be converted to
804         * exactly the same BigDecimal with the same scale.
805         * For example, the literal '1.45d' will be converted to '1.45'.
806         * <p>
807         * This instance is immutable and unaffected by this method.
808         * 
809         * @param amountToAdd  the monetary value to add, not null
810         * @return the new instance with the input amount added, never null
811         * @throws ArithmeticException if the scale of the amount is too large
812         */
813        public Money plus(double amountToAdd) {
814            return plus(amountToAdd, RoundingMode.UNNECESSARY);
815        }
816    
817        /**
818         * Returns a copy of this monetary value with the amount added.
819         * <p>
820         * This adds the specified amount to this monetary amount, returning a new object.
821         * If the amount to add exceeds the scale of the currency, then the
822         * rounding mode will be used to adjust the result.
823         * <p>
824         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
825         * the most expected answer for most programming scenarios.
826         * Any {@code double} literal in code will be converted to
827         * exactly the same BigDecimal with the same scale.
828         * For example, the literal '1.45d' will be converted to '1.45'.
829         * <p>
830         * This instance is immutable and unaffected by this method.
831         * 
832         * @param amountToAdd  the monetary value to add, not null
833         * @param roundingMode  the rounding mode to use, not null
834         * @return the new instance with the input amount added, never null
835         */
836        public Money plus(double amountToAdd, RoundingMode roundingMode) {
837            return with(money.plusRetainScale(amountToAdd, roundingMode));
838        }
839    
840        /**
841         * Returns a copy of this monetary value with the amount in major units added.
842         * <p>
843         * This adds an amount in major units, leaving the minor units untouched.
844         * For example, USD 23.45 plus 138 gives USD 161.45.
845         * <p>
846         * This instance is immutable and unaffected by this method.
847         * 
848         * @param amountToAdd  the monetary value to add, not null
849         * @return the new instance with the input amount added, never null
850         */
851        public Money plusMajor(long amountToAdd) {
852            return with(money.plusMajor(amountToAdd));
853        }
854    
855        /**
856         * Returns a copy of this monetary value with the amount in minor units added.
857         * <p>
858         * This adds an amount in minor units.
859         * For example, USD 23.45 plus 138 gives USD 24.83.
860         * <p>
861         * This instance is immutable and unaffected by this method.
862         * 
863         * @param amountToAdd  the monetary value to add, not null
864         * @return the new instance with the input amount added, never null
865         */
866        public Money plusMinor(long amountToAdd) {
867            return with(money.plusMinor(amountToAdd));
868        }
869    
870        //-----------------------------------------------------------------------
871        /**
872         * Returns a copy of this monetary value with a collection of monetary amounts subtracted.
873         * <p>
874         * This subtracts the specified amounts from this monetary amount, returning a new object.
875         * The amounts must be in the same currency.
876         * <p>
877         * This instance is immutable and unaffected by this method.
878         * 
879         * @param moniesToSubtract  the monetary values to subtract, no null elements, not null
880         * @return the new instance with the input amounts subtracted, never null
881         * @throws CurrencyMismatchException if the currencies differ
882         */
883        public Money minus(Iterable<Money> moniesToSubtract) {
884            return with(money.minus(moniesToSubtract));
885        }
886    
887        //-----------------------------------------------------------------------
888        /**
889         * Returns a copy of this monetary value with the amount subtracted.
890         * <p>
891         * This subtracts the specified amount from this monetary amount, returning a new object.
892         * The amount subtracted must be in the same currency.
893         * <p>
894         * The subtraction has no rounding issues and is always accurate.
895         * For example,'USD 25.95' minus 'USD 3.02' will 'USD 22.93'.
896         * <p>
897         * This instance is immutable and unaffected by this method.
898         * 
899         * @param moneyToSubtract  the monetary value to subtract, not null
900         * @return the new instance with the input amount subtracted, never null
901         * @throws CurrencyMismatchException if the currencies differ
902         */
903        public Money minus(Money moneyToSubtract) {
904            return with(money.minus(moneyToSubtract));
905        }
906    
907        /**
908         * Returns a copy of this monetary value with the amount subtracted.
909         * <p>
910         * This subtracts the specified amount from this monetary amount, returning a new object.
911         * No rounding is performed on the amount to be subtracted, so it must have a
912         * scale compatible with the currency.
913         * <p>
914         * This instance is immutable and unaffected by this method.
915         * 
916         * @param amountToSubtract  the monetary value to subtract, not null
917         * @return the new instance with the input amount subtracted, never null
918         * @throws ArithmeticException if the scale of the amount is too large
919         */
920        public Money minus(BigDecimal amountToSubtract) {
921            return minus(amountToSubtract, RoundingMode.UNNECESSARY);
922        }
923    
924        /**
925         * Returns a copy of this monetary value with the amount subtracted.
926         * <p>
927         * This subtracts the specified amount from this monetary amount, returning a new object.
928         * If the amount to subtract exceeds the scale of the currency, then the
929         * rounding mode will be used to adjust the result.
930         * <p>
931         * This instance is immutable and unaffected by this method.
932         * 
933         * @param amountToSubtract  the monetary value to subtract, not null
934         * @param roundingMode  the rounding mode to use, not null
935         * @return the new instance with the input amount subtracted, never null
936         */
937        public Money minus(BigDecimal amountToSubtract, RoundingMode roundingMode) {
938            return with(money.minusRetainScale(amountToSubtract, roundingMode));
939        }
940    
941        /**
942         * Returns a copy of this monetary value with the amount subtracted.
943         * <p>
944         * This subtracts the specified amount from this monetary amount, returning a new object.
945         * No rounding is performed on the amount to be subtracted, so it must have a
946         * scale compatible with the currency.
947         * <p>
948         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
949         * the most expected answer for most programming scenarios.
950         * Any {@code double} literal in code will be converted to
951         * exactly the same BigDecimal with the same scale.
952         * For example, the literal '1.45d' will be converted to '1.45'.
953         * <p>
954         * This instance is immutable and unaffected by this method.
955         * 
956         * @param amountToSubtract  the monetary value to subtract, not null
957         * @return the new instance with the input amount subtracted, never null
958         * @throws ArithmeticException if the scale of the amount is too large
959         */
960        public Money minus(double amountToSubtract) {
961            return minus(amountToSubtract, RoundingMode.UNNECESSARY);
962        }
963    
964        /**
965         * Returns a copy of this monetary value with the amount subtracted.
966         * <p>
967         * This subtracts the specified amount from this monetary amount, returning a new object.
968         * If the amount to subtract exceeds the scale of the currency, then the
969         * rounding mode will be used to adjust the result.
970         * <p>
971         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
972         * the most expected answer for most programming scenarios.
973         * Any {@code double} literal in code will be converted to
974         * exactly the same BigDecimal with the same scale.
975         * For example, the literal '1.45d' will be converted to '1.45'.
976         * <p>
977         * This instance is immutable and unaffected by this method.
978         * 
979         * @param amountToSubtract  the monetary value to subtract, not null
980         * @param roundingMode  the rounding mode to use, not null
981         * @return the new instance with the input amount subtracted, never null
982         */
983        public Money minus(double amountToSubtract, RoundingMode roundingMode) {
984            return with(money.minusRetainScale(amountToSubtract, roundingMode));
985        }
986    
987        /**
988         * Returns a copy of this monetary value with the amount in major units subtracted.
989         * <p>
990         * This subtracts an amount in major units, leaving the minor units untouched.
991         * For example, USD 23.45 minus 138 gives USD -114.55.
992         * <p>
993         * This instance is immutable and unaffected by this method.
994         * 
995         * @param amountToSubtract  the monetary value to subtract, not null
996         * @return the new instance with the input amount subtracted, never null
997         */
998        public Money minusMajor(long amountToSubtract) {
999            return with(money.minusMajor(amountToSubtract));
1000        }
1001    
1002        /**
1003         * Returns a copy of this monetary value with the amount in minor units subtracted.
1004         * <p>
1005         * This subtracts an amount in minor units.
1006         * For example, USD 23.45 minus 138 gives USD 22.07.
1007         * <p>
1008         * This instance is immutable and unaffected by this method.
1009         * 
1010         * @param amountToSubtract  the monetary value to subtract, not null
1011         * @return the new instance with the input amount subtracted, never null
1012         */
1013        public Money minusMinor(long amountToSubtract) {
1014            return with(money.minusMinor(amountToSubtract));
1015        }
1016    
1017        //-----------------------------------------------------------------------
1018        /**
1019         * Returns a copy of this monetary value multiplied by the specified value.
1020         * <p>
1021         * This takes this amount and multiplies it by the specified value, rounding
1022         * the result is rounded as specified.
1023         * <p>
1024         * This instance is immutable and unaffected by this method.
1025         * 
1026         * @param valueToMultiplyBy  the scalar value to multiply by, not null
1027         * @param roundingMode  the rounding mode to use to bring the decimal places back in line, not null
1028         * @return the new multiplied instance, never null
1029         * @throws ArithmeticException if the rounding fails
1030         */
1031        public Money multipliedBy(BigDecimal valueToMultiplyBy, RoundingMode roundingMode) {
1032            return with(money.multiplyRetainScale(valueToMultiplyBy, roundingMode));
1033        }
1034    
1035        /**
1036         * Returns a copy of this monetary value multiplied by the specified value.
1037         * <p>
1038         * This takes this amount and multiplies it by the specified value, rounding
1039         * the result is rounded as specified.
1040         * <p>
1041         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
1042         * the most expected answer for most programming scenarios.
1043         * Any {@code double} literal in code will be converted to
1044         * exactly the same BigDecimal with the same scale.
1045         * For example, the literal '1.45d' will be converted to '1.45'.
1046         * <p>
1047         * This instance is immutable and unaffected by this method.
1048         * 
1049         * @param valueToMultiplyBy  the scalar value to multiply by, not null
1050         * @param roundingMode  the rounding mode to use to bring the decimal places back in line, not null
1051         * @return the new multiplied instance, never null
1052         * @throws ArithmeticException if the rounding fails
1053         */
1054        public Money multipliedBy(double valueToMultiplyBy, RoundingMode roundingMode) {
1055            return with(money.multiplyRetainScale(valueToMultiplyBy, roundingMode));
1056        }
1057    
1058        /**
1059         * Returns a copy of this monetary value multiplied by the specified value.
1060         * <p>
1061         * This takes this amount and multiplies it by the specified value.
1062         * <p>
1063         * This instance is immutable and unaffected by this method.
1064         * 
1065         * @param valueToMultiplyBy  the scalar value to multiply by, not null
1066         * @return the new multiplied instance, never null
1067         */
1068        public Money multipliedBy(long valueToMultiplyBy) {
1069            return with(money.multipliedBy(valueToMultiplyBy));
1070        }
1071    
1072        //-----------------------------------------------------------------------
1073        /**
1074         * Returns a copy of this monetary value divided by the specified value.
1075         * <p>
1076         * This takes this amount and divides it by the specified value, rounding
1077         * the result is rounded as specified.
1078         * <p>
1079         * This instance is immutable and unaffected by this method.
1080         * 
1081         * @param valueToDivideBy  the scalar value to divide by, not null
1082         * @param roundingMode  the rounding mode to use, not null
1083         * @return the new divided instance, never null
1084         * @throws ArithmeticException if dividing by zero
1085         * @throws ArithmeticException if the rounding fails
1086         */
1087        public Money dividedBy(BigDecimal valueToDivideBy, RoundingMode roundingMode) {
1088            return with(money.dividedBy(valueToDivideBy, roundingMode));
1089        }
1090    
1091        /**
1092         * Returns a copy of this monetary value divided by the specified value.
1093         * <p>
1094         * This takes this amount and divides it by the specified value, rounding
1095         * the result is rounded as specified.
1096         * <p>
1097         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
1098         * the most expected answer for most programming scenarios.
1099         * Any {@code double} literal in code will be converted to
1100         * exactly the same BigDecimal with the same scale.
1101         * For example, the literal '1.45d' will be converted to '1.45'.
1102         * <p>
1103         * This instance is immutable and unaffected by this method.
1104         * 
1105         * @param valueToDivideBy  the scalar value to divide by, not null
1106         * @param roundingMode  the rounding mode to use, not null
1107         * @return the new divided instance, never null
1108         * @throws ArithmeticException if dividing by zero
1109         * @throws ArithmeticException if the rounding fails
1110         */
1111        public Money dividedBy(double valueToDivideBy, RoundingMode roundingMode) {
1112            return with(money.dividedBy(valueToDivideBy, roundingMode));
1113        }
1114    
1115        /**
1116         * Returns a copy of this monetary value divided by the specified value.
1117         * <p>
1118         * This takes this amount and divides it by the specified value, rounding
1119         * the result is rounded as specified.
1120         * <p>
1121         * This instance is immutable and unaffected by this method.
1122         * 
1123         * @param valueToDivideBy  the scalar value to divide by, not null
1124         * @param roundingMode  the rounding mode to use, not null
1125         * @return the new divided instance, never null
1126         * @throws ArithmeticException if dividing by zero
1127         * @throws ArithmeticException if the rounding fails
1128         */
1129        public Money dividedBy(long valueToDivideBy, RoundingMode roundingMode) {
1130            return with(money.dividedBy(valueToDivideBy, roundingMode));
1131        }
1132    
1133        //-----------------------------------------------------------------------
1134        /**
1135         * Returns a copy of this monetary value with the amount negated.
1136         * <p>
1137         * This instance is immutable and unaffected by this method.
1138         * 
1139         * @return the new instance with the amount negated, never null
1140         */
1141        public Money negated() {
1142            return with(money.negated());
1143        }
1144    
1145        /**
1146         * Returns a copy of this monetary value with a positive amount.
1147         * <p>
1148         * This instance is immutable and unaffected by this method.
1149         * 
1150         * @return the new instance with the amount converted to be positive, never null
1151         */
1152        public Money abs() {
1153            return (isNegative() ? negated() : this);
1154        }
1155    
1156        //-----------------------------------------------------------------------
1157        /**
1158         * Returns a copy of this monetary value rounded to the specified scale without
1159         * changing the current scale.
1160         * <p>
1161         * Scale has the same meaning as in {@link BigDecimal}.
1162         * A scale of 2 means round to 2 decimal places.
1163         * <ul>
1164         * <li>Rounding 'EUR 45.23' to a scale of -1 returns 40.00 or 50.00 depending on the rounding mode.
1165         * <li>Rounding 'EUR 45.23' to a scale of 0 returns 45.00 or 46.00 depending on the rounding mode.
1166         * <li>Rounding 'EUR 45.23' to a scale of 1 returns 45.20 or 45.30 depending on the rounding mode.
1167         * <li>Rounding 'EUR 45.23' to a scale of 2 has no effect (it already has that scale).
1168         * <li>Rounding 'EUR 45.23' to a scale of 3 has no effect (the scale is not increased).
1169         * </ul>
1170         * <p>
1171         * This instance is immutable and unaffected by this method.
1172         * 
1173         * @param scale  the new scale
1174         * @param roundingMode  the rounding mode to use, not null
1175         * @return the new instance with the amount converted to be positive, never null
1176         * @throws ArithmeticException if the rounding fails
1177         */
1178        public Money rounded(int scale, RoundingMode roundingMode) {
1179            return with(money.rounded(scale, roundingMode));
1180        }
1181    
1182        //-----------------------------------------------------------------------
1183        /**
1184         * Returns a copy of this monetary value converted into another currency
1185         * using the specified conversion rate, with a rounding mode used to adjust
1186         * the decimal places in the result.
1187         * <p>
1188         * This instance is immutable and unaffected by this method.
1189         * 
1190         * @param currency  the new currency, not null
1191         * @param conversionMultipler  the conversion factor between the currencies, not null
1192         * @param roundingMode  the rounding mode to use to bring the decimal places back in line, not null
1193         * @return the new multiplied instance, never null
1194         * @throws IllegalArgumentException if the currency is the same as this currency
1195         * @throws IllegalArgumentException if the conversion multiplier is negative
1196         * @throws ArithmeticException if the rounding fails
1197         */
1198        public Money convertedTo(CurrencyUnit currency, BigDecimal conversionMultipler, RoundingMode roundingMode) {
1199            return with(money.convertedTo(currency, conversionMultipler).withCurrencyScale(roundingMode));
1200        }
1201    
1202        //-----------------------------------------------------------------------
1203        /**
1204         * Implements the {@code BigMoneyProvider} interface, returning a
1205         * {@code BigMoney} instance with the same currency, amount and scale.
1206         * 
1207         * @return the money instance, never null
1208         */
1209        public BigMoney toBigMoney() {
1210            return money;
1211        }
1212    
1213        //-----------------------------------------------------------------------
1214        /**
1215         * Checks if this instance and the specified instance have the same currency.
1216         * 
1217         * @param other  the money to check, not null
1218         * @return true if they have the same currency
1219         */
1220        public boolean isSameCurrency(BigMoneyProvider other) {
1221            return money.isSameCurrency(other);
1222        }
1223    
1224        //-----------------------------------------------------------------------
1225        /**
1226         * Compares this monetary value to another.
1227         * <p>
1228         * This allows {@code Money} to be compared to any {@code BigMoneyProvider}.
1229         * Scale is ignored in the comparison.
1230         * The compared values must be in the same currency.
1231         * 
1232         * @param other  the other monetary value, not null
1233         * @return -1 if this is less than , 0 if equal, 1 if greater than
1234         * @throws CurrencyMismatchException if the currencies differ
1235         */
1236        public int compareTo(BigMoneyProvider other) {
1237            return money.compareTo(other);
1238        }
1239    
1240        /**
1241         * Checks if this monetary value is equal to another.
1242         * <p>
1243         * This allows {@code Money} to be compared to any {@code BigMoneyProvider}.
1244         * Scale is ignored, so 'USD 30.00' and 'USD 30' are equal.
1245         * The compared values must be in the same currency.
1246         * 
1247         * @param other  the other monetary value, not null
1248         * @return true is this is greater than the specified monetary value
1249         * @throws CurrencyMismatchException if the currencies differ
1250         * @see #equals(Object)
1251         */
1252        public boolean isEqual(BigMoneyProvider other) {
1253            return money.isEqual(other);
1254        }
1255    
1256        /**
1257         * Checks if this monetary value is greater than another.
1258         * <p>
1259         * This allows {@code Money} to be compared to any {@code BigMoneyProvider}.
1260         * Scale is ignored in the comparison.
1261         * The compared values must be in the same currency.
1262         * 
1263         * @param other  the other monetary value, not null
1264         * @return true is this is greater than the specified monetary value
1265         * @throws CurrencyMismatchException if the currencies differ
1266         */
1267        public boolean isGreaterThan(BigMoneyProvider other) {
1268            return money.isGreaterThan(other);
1269        }
1270    
1271        /**
1272         * Checks if this monetary value is less than another.
1273         * <p>
1274         * This allows {@code Money} to be compared to any {@code BigMoneyProvider}.
1275         * Scale is ignored in the comparison.
1276         * The compared values must be in the same currency.
1277         * 
1278         * @param other  the other monetary value, not null
1279         * @return true is this is less than the specified monetary value
1280         * @throws CurrencyMismatchException if the currencies differ
1281         */
1282        public boolean isLessThan(BigMoneyProvider other) {
1283            return money.isLessThan(other);
1284        }
1285    
1286        //-----------------------------------------------------------------------
1287        /**
1288         * Checks if this monetary value equals another.
1289         * <p>
1290         * The comparison takes into account the scale.
1291         * The compared values must be in the same currency.
1292         * 
1293         * @param other  the other object to compare to, not null
1294         * @return true if this instance equals the other instance
1295         */
1296        @Override
1297        public boolean equals(Object other) {
1298            if (this == other) {
1299                return true;
1300            }
1301            if (other instanceof Money) {
1302                Money otherMoney = (Money) other;
1303                return money.equals(otherMoney.money);
1304            }
1305            return false;
1306        }
1307    
1308        /**
1309         * Returns a hash code for this monetary value.
1310         * 
1311         * @return a suitable hash code
1312         */
1313        @Override
1314        public int hashCode() {
1315            return money.hashCode() + 3;
1316        }
1317    
1318        //-----------------------------------------------------------------------
1319        /**
1320         * Gets the monetary value as a string.
1321         * <p>
1322         * The format is the 3 letter ISO currency code, followed by a space,
1323         * followed by the amount as per {@link BigDecimal#toPlainString()}.
1324         * 
1325         * @return the string representation of this monetary value, never null
1326         */
1327        @Override
1328        @ToString
1329        public String toString() {
1330            return money.toString();
1331        }
1332    
1333    }