View Javadoc

1   /*
2    *  Copyright 2009-2013 Stephen Colebourne
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package org.joda.money;
17  
18  import java.io.InvalidObjectException;
19  import java.io.ObjectInputStream;
20  import java.io.Serializable;
21  import java.math.BigDecimal;
22  import java.math.RoundingMode;
23  import java.util.Arrays;
24  import java.util.Iterator;
25  
26  import org.joda.convert.FromString;
27  import org.joda.convert.ToString;
28  
29  /**
30   * An amount of money with the standard decimal places defined by the currency.
31   * <p>
32   * This class represents a quantity of money, stored as a {@code BigDecimal} amount
33   * in a single {@link CurrencyUnit currency}.
34   * <p>
35   * Every currency has a certain standard number of decimal places.
36   * This is typically 2 (Euro, British Pound, US Dollar) but might be
37   * 0 (Japanese Yen), 1 (Vietnamese Dong) or 3 (Bahrain Dinar).
38   * The {@code Money} class is fixed to this number of decimal places.
39   * <p>
40   * For example, US dollars has a standard number of decimal places of 2.
41   * The major units are dollars. The minor units are cents, 100 to the dollar.
42   * This class does not allow calculations on fractions of a cent.
43   * <p>
44   * This class is immutable and thread-safe.
45   */
46  public final class Money implements BigMoneyProvider, Comparable<BigMoneyProvider>, Serializable {
47  
48      /**
49       * The serialisation version.
50       */
51      private static final long serialVersionUID = 1L;
52  
53      /**
54       * The money, not null.
55       */
56      private final BigMoney money;
57  
58      //-----------------------------------------------------------------------
59      /**
60       * Obtains an instance of {@code Money} from a {@code BigDecimal}.
61       * <p>
62       * This allows you to create an instance with a specific currency and amount.
63       * No rounding is performed on the amount, so it must have a scale compatible
64       * with the currency.
65       *
66       * @param currency  the currency, not null
67       * @param amount  the amount of money, not null
68       * @return the new instance, never null
69       * @throws ArithmeticException if the scale exceeds the currency scale
70       */
71      public static Money of(CurrencyUnit currency, BigDecimal amount) {
72          MoneyUtils.checkNotNull(currency, "Currency must not be null");
73          if (amount.scale() > currency.getDecimalPlaces()) {
74              throw new ArithmeticException("Scale of amount " + amount + " is greater than the scale of the currency " + currency);
75          }
76          return Money.of(currency, amount, RoundingMode.UNNECESSARY);
77      }
78  
79      /**
80       * Obtains an instance of {@code Money} from a {@code BigDecimal}, rounding as necessary.
81       * <p>
82       * This allows you to create an instance with a specific currency and amount.
83       * If the amount has a scale in excess of the scale of the currency then the excess
84       * fractional digits are rounded using the rounding mode.
85       *
86       * @param currency  the currency, not null
87       * @param amount  the amount of money, not null
88       * @param roundingMode  the rounding mode to use, not null
89       * @return the new instance, never null
90       * @throws ArithmeticException if the rounding fails
91       */
92      public static Money of(CurrencyUnit currency, BigDecimal amount, RoundingMode roundingMode) {
93          MoneyUtils.checkNotNull(currency, "CurrencyUnit must not be null");
94          MoneyUtils.checkNotNull(amount, "Amount must not be null");
95          MoneyUtils.checkNotNull(roundingMode, "RoundingMode must not be null");
96          amount = amount.setScale(currency.getDecimalPlaces(), roundingMode);
97          return new Money(BigMoney.of(currency, amount));
98      }
99  
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 }