001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      https://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.lang3;
018
019import java.util.Arrays;
020import java.util.Collections;
021import java.util.List;
022import java.util.function.Consumer;
023
024import org.apache.commons.lang3.math.NumberUtils;
025
026/**
027 * Operations on boolean primitives and Boolean objects.
028 *
029 * <p>
030 * This class tries to handle {@code null} input gracefully.
031 * An exception will not be thrown for a {@code null} input.
032 * Each method documents its behavior in more detail.
033 * </p>
034 *
035 * <p>
036 * #ThreadSafe#
037 * </p>
038 *
039 * @since 2.0
040 */
041public class BooleanUtils {
042
043    private static final List<Boolean> BOOLEAN_LIST = Collections.unmodifiableList(Arrays.asList(Boolean.FALSE, Boolean.TRUE));
044
045    /**
046     * The false String {@code "false"}.
047     *
048     * @since 3.12.0
049     */
050    public static final String FALSE = "false";
051
052    /**
053     * The no String {@code "no"}.
054     *
055     * @since 3.12.0
056     */
057    public static final String NO = "no";
058
059    /**
060     * The off String {@code "off"}.
061     *
062     * @since 3.12.0
063     */
064    public static final String OFF = "off";
065
066    /**
067     * The on String {@code "on"}.
068     *
069     * @since 3.12.0
070     */
071    public static final String ON = "on";
072
073    /**
074     * The true String {@code "true"}.
075     *
076     * @since 3.12.0
077     */
078    public static final String TRUE = "true";
079
080    /**
081     * The yes String {@code "yes"}.
082     *
083     * @since 3.12.0
084     */
085    public static final String YES = "yes";
086
087    /**
088     * Performs an 'and' operation on a set of booleans.
089     *
090     * <pre>
091     *   BooleanUtils.and(true, true)         = true
092     *   BooleanUtils.and(false, false)       = false
093     *   BooleanUtils.and(true, false)        = false
094     *   BooleanUtils.and(true, true, false)  = false
095     *   BooleanUtils.and(true, true, true)   = true
096     * </pre>
097     *
098     * @param array  An array of {@code boolean}s
099     * @return The result of the logical 'and' operation. That is {@code false}
100     * if any of the parameters is {@code false} and {@code true} otherwise.
101     * @throws NullPointerException Thrown if {@code array} is {@code null}.
102     * @throws IllegalArgumentException Thrown if {@code array} is empty.
103     * @since 3.0.1
104     */
105    public static boolean and(final boolean... array) {
106        ObjectUtils.requireNonEmpty(array, "array");
107        for (final boolean element : array) {
108            if (!element) {
109                return false;
110            }
111        }
112        return true;
113    }
114
115    /**
116     * Performs an 'and' operation on an array of Booleans.
117     * <pre>
118     *   BooleanUtils.and(Boolean.TRUE, Boolean.TRUE)                 = Boolean.TRUE
119     *   BooleanUtils.and(Boolean.FALSE, Boolean.FALSE)               = Boolean.FALSE
120     *   BooleanUtils.and(Boolean.TRUE, Boolean.FALSE)                = Boolean.FALSE
121     *   BooleanUtils.and(Boolean.TRUE, Boolean.TRUE, Boolean.TRUE)   = Boolean.TRUE
122     *   BooleanUtils.and(Boolean.FALSE, Boolean.FALSE, Boolean.TRUE) = Boolean.FALSE
123     *   BooleanUtils.and(Boolean.TRUE, Boolean.FALSE, Boolean.TRUE)  = Boolean.FALSE
124     *   BooleanUtils.and(null, null)                                 = Boolean.FALSE
125     * </pre>
126     * <p>
127     * Null array elements map to false, like {@code Boolean.parseBoolean(null)} and its callers return false.
128     * </p>
129     *
130     * @param array  An array of {@link Boolean}s
131     * @return The result of the logical 'and' operation. That is {@code false}
132     * if any of the parameters is {@code false} and {@code true} otherwise.
133     * @throws NullPointerException Thrown if {@code array} is {@code null}.
134     * @throws IllegalArgumentException Thrown if {@code array} is empty.
135     * @since 3.0.1
136     */
137    public static Boolean and(final Boolean... array) {
138        ObjectUtils.requireNonEmpty(array, "array");
139        return and(ArrayUtils.toPrimitive(array)) ? Boolean.TRUE : Boolean.FALSE;
140    }
141
142    /**
143     * Returns a new array of possible values (like an enum would).
144     *
145     * @return A new array of possible values (like an enum would).
146     * @since 3.12.0
147     */
148    public static Boolean[] booleanValues() {
149        return new Boolean[] {Boolean.FALSE, Boolean.TRUE};
150    }
151
152    /**
153     * Compares two {@code boolean} values. This is the same functionality as provided in Java 7.
154     *
155     * @param x The first {@code boolean} to compare
156     * @param y The second {@code boolean} to compare
157     * @return The value {@code 0} if {@code x == y};
158     *         a value less than {@code 0} if {@code !x && y}; and
159     *         a value greater than {@code 0} if {@code x && !y}
160     * @since 3.4
161     */
162    public static int compare(final boolean x, final boolean y) {
163        if (x == y) {
164            return 0;
165        }
166        return x ? 1 : -1;
167    }
168
169    /**
170     * Performs the given action for each Boolean {@link BooleanUtils#values()}.
171     *
172     * @param action The action to be performed for each element
173     * @since 3.13.0
174     */
175    public static void forEach(final Consumer<Boolean> action) {
176        values().forEach(action);
177    }
178
179    /**
180     * Tests whether a {@link Boolean} value is {@code false}, handling {@code null} by returning {@code false}.
181     *
182     * <pre>
183     *   BooleanUtils.isFalse(Boolean.TRUE)  = false
184     *   BooleanUtils.isFalse(Boolean.FALSE) = true
185     *   BooleanUtils.isFalse(null)          = false
186     * </pre>
187     *
188     * @param bool  The boolean to check, null returns {@code false}
189     * @return {@code true} only if the input is non-{@code null} and {@code false}
190     * @since 2.1
191     */
192    public static boolean isFalse(final Boolean bool) {
193        return Boolean.FALSE.equals(bool);
194    }
195
196    /**
197     * Tests whether a {@link Boolean} value is <em>not</em> {@code false}, handling {@code null} by returning {@code true}.
198     *
199     * <pre>
200     *   BooleanUtils.isNotFalse(Boolean.TRUE)  = true
201     *   BooleanUtils.isNotFalse(Boolean.FALSE) = false
202     *   BooleanUtils.isNotFalse(null)          = true
203     * </pre>
204     *
205     * @param bool  The boolean to check, null returns {@code true}
206     * @return {@code true} if the input is {@code null} or {@code true}
207     * @since 2.3
208     */
209    public static boolean isNotFalse(final Boolean bool) {
210        return !isFalse(bool);
211    }
212
213    /**
214     * Tests whether a {@link Boolean} value is <em>not</em> {@code true}, handling {@code null} by returning {@code true}.
215     *
216     * <pre>
217     *   BooleanUtils.isNotTrue(Boolean.TRUE)  = false
218     *   BooleanUtils.isNotTrue(Boolean.FALSE) = true
219     *   BooleanUtils.isNotTrue(null)          = true
220     * </pre>
221     *
222     * @param bool  The boolean to check, null returns {@code true}
223     * @return {@code true} if the input is null or false
224     * @since 2.3
225     */
226    public static boolean isNotTrue(final Boolean bool) {
227        return !isTrue(bool);
228    }
229
230    /**
231     * Tests whether a {@link Boolean} value is {@code true}, handling {@code null} by returning {@code false}.
232     *
233     * <pre>
234     *   BooleanUtils.isTrue(Boolean.TRUE)  = true
235     *   BooleanUtils.isTrue(Boolean.FALSE) = false
236     *   BooleanUtils.isTrue(null)          = false
237     * </pre>
238     *
239     * @param bool The boolean to check, {@code null} returns {@code false}
240     * @return {@code true} only if the input is non-null and true
241     * @since 2.1
242     */
243    public static boolean isTrue(final Boolean bool) {
244        return Boolean.TRUE.equals(bool);
245    }
246
247    /**
248     * Negates the specified boolean.
249     *
250     * <p>
251     * If {@code null} is passed in, {@code null} will be returned.
252     * </p>
253     *
254     * <p>
255     * NOTE: This returns {@code null} and will throw a {@link NullPointerException}
256     * if unboxed to a boolean.
257     * </p>
258     *
259     * <pre>
260     *   BooleanUtils.negate(Boolean.TRUE)  = Boolean.FALSE;
261     *   BooleanUtils.negate(Boolean.FALSE) = Boolean.TRUE;
262     *   BooleanUtils.negate(null)          = null;
263     * </pre>
264     *
265     * @param bool  The Boolean to negate, may be null
266     * @return The negated Boolean, or {@code null} if {@code null} input
267     */
268    public static Boolean negate(final Boolean bool) {
269        if (bool == null) {
270            return null;
271        }
272        return bool.booleanValue() ? Boolean.FALSE : Boolean.TRUE;
273    }
274
275    /**
276     * Performs a one-hot on an array of booleans.
277     * <p>
278     * This implementation returns true if one, and only one, of the supplied values is true.
279     * </p>
280     * <p>
281     * See also <a href="https://en.wikipedia.org/wiki/One-hot">One-hot</a>.
282     * </p>
283     *
284     * @param array  An array of {@code boolean}s
285     * @return The result of the one-hot operations
286     * @throws NullPointerException Thrown if {@code array} is {@code null}.
287     * @throws IllegalArgumentException Thrown if {@code array} is empty.
288     */
289    public static boolean oneHot(final boolean... array) {
290        ObjectUtils.requireNonEmpty(array, "array");
291        boolean result = false;
292        for (final boolean element: array) {
293            if (element) {
294                if (result) {
295                    return false;
296                }
297                result = true;
298            }
299        }
300        return result;
301    }
302
303    /**
304     * Performs a one-hot on an array of booleans.
305     * <p>
306     * This implementation returns true if one, and only one, of the supplied values is true.
307     * </p>
308     * <p>
309     * Null array elements map to false, like {@code Boolean.parseBoolean(null)} and its callers return false.
310     * </p>
311     * <p>
312     * See also <a href="https://en.wikipedia.org/wiki/One-hot">One-hot</a>.
313     * </p>
314     *
315     * @param array  An array of {@code boolean}s
316     * @return The result of the one-hot operations
317     * @throws NullPointerException Thrown if {@code array} is {@code null}.
318     * @throws IllegalArgumentException Thrown if {@code array} is empty.
319     */
320    public static Boolean oneHot(final Boolean... array) {
321        return Boolean.valueOf(oneHot(ArrayUtils.toPrimitive(array)));
322    }
323
324    /**
325     * Performs an 'or' operation on a set of booleans.
326     *
327     * <pre>
328     *   BooleanUtils.or(true, true)          = true
329     *   BooleanUtils.or(false, false)        = false
330     *   BooleanUtils.or(true, false)         = true
331     *   BooleanUtils.or(true, true, false)   = true
332     *   BooleanUtils.or(true, true, true)    = true
333     *   BooleanUtils.or(false, false, false) = false
334     * </pre>
335     *
336     * @param array  An array of {@code boolean}s
337     * @return {@code true} if any of the arguments is {@code true}, and it returns {@code false} otherwise.
338     * @throws NullPointerException Thrown if {@code array} is {@code null}.
339     * @throws IllegalArgumentException Thrown if {@code array} is empty.
340     * @since 3.0.1
341     */
342    public static boolean or(final boolean... array) {
343        ObjectUtils.requireNonEmpty(array, "array");
344        for (final boolean element : array) {
345            if (element) {
346                return true;
347            }
348        }
349        return false;
350    }
351
352    /**
353     * Performs an 'or' operation on an array of Booleans.
354     * <pre>
355     *   BooleanUtils.or(Boolean.TRUE, Boolean.TRUE)                  = Boolean.TRUE
356     *   BooleanUtils.or(Boolean.FALSE, Boolean.FALSE)                = Boolean.FALSE
357     *   BooleanUtils.or(Boolean.TRUE, Boolean.FALSE)                 = Boolean.TRUE
358     *   BooleanUtils.or(Boolean.TRUE, Boolean.TRUE, Boolean.TRUE)    = Boolean.TRUE
359     *   BooleanUtils.or(Boolean.FALSE, Boolean.FALSE, Boolean.TRUE)  = Boolean.TRUE
360     *   BooleanUtils.or(Boolean.TRUE, Boolean.FALSE, Boolean.TRUE)   = Boolean.TRUE
361     *   BooleanUtils.or(Boolean.FALSE, Boolean.FALSE, Boolean.FALSE) = Boolean.FALSE
362     *   BooleanUtils.or(Boolean.TRUE, null)                          = Boolean.TRUE
363     *   BooleanUtils.or(Boolean.FALSE, null)                         = Boolean.FALSE
364     * </pre>
365     * <p>
366     * Null array elements map to false, like {@code Boolean.parseBoolean(null)} and its callers return false.
367     * </p>
368     *
369     * @param array  An array of {@link Boolean}s
370     * @return {@code true} if any of the arguments is {@code true}, and it returns {@code false} otherwise.
371     * @throws NullPointerException Thrown if {@code array} is {@code null}.
372     * @throws IllegalArgumentException Thrown if {@code array} is empty.
373     * @since 3.0.1
374     */
375    public static Boolean or(final Boolean... array) {
376        ObjectUtils.requireNonEmpty(array, "array");
377        return or(ArrayUtils.toPrimitive(array)) ? Boolean.TRUE : Boolean.FALSE;
378    }
379
380    /**
381     * Returns a new array of possible values (like an enum would).
382     *
383     * @return A new array of possible values (like an enum would).
384     * @since 3.12.0
385     */
386    public static boolean[] primitiveValues() {
387        return new boolean[] {false, true};
388    }
389
390    /**
391     * Converts a Boolean to a boolean handling {@code null}
392     * by returning {@code false}.
393     *
394     * <pre>
395     *   BooleanUtils.toBoolean(Boolean.TRUE)  = true
396     *   BooleanUtils.toBoolean(Boolean.FALSE) = false
397     *   BooleanUtils.toBoolean(null)          = false
398     * </pre>
399     *
400     * @param bool  The boolean to convert
401     * @return {@code true} or {@code false}, {@code null} returns {@code false}
402     */
403    public static boolean toBoolean(final Boolean bool) {
404        return bool != null && bool.booleanValue();
405    }
406
407    /**
408     * Converts an int to a boolean using the convention that {@code zero}
409     * is {@code false}, everything else is {@code true}.
410     *
411     * <pre>
412     *   BooleanUtils.toBoolean(0) = false
413     *   BooleanUtils.toBoolean(1) = true
414     *   BooleanUtils.toBoolean(2) = true
415     * </pre>
416     *
417     * @param value  The int to convert
418     * @return {@code true} if non-zero, {@code false}
419     *  if zero
420     */
421    public static boolean toBoolean(final int value) {
422        return value != 0;
423    }
424
425    /**
426     * Converts an int to a boolean specifying the conversion values.
427     *
428     * <p>
429     * If the {@code trueValue} and {@code falseValue} are the same number then
430     * the return value will be {@code true} in case {@code value} matches it.
431     * </p>
432     *
433     * <pre>
434     *   BooleanUtils.toBoolean(0, 1, 0) = false
435     *   BooleanUtils.toBoolean(1, 1, 0) = true
436     *   BooleanUtils.toBoolean(1, 1, 1) = true
437     *   BooleanUtils.toBoolean(2, 1, 2) = false
438     *   BooleanUtils.toBoolean(2, 2, 0) = true
439     * </pre>
440     *
441     * @param value  The {@link Integer} to convert
442     * @param trueValue  The value to match for {@code true}
443     * @param falseValue  The value to match for {@code false}
444     * @return {@code true} or {@code false}
445     * @throws IllegalArgumentException Thrown if {@code value} does not match neither {@code trueValue} no {@code falseValue}.
446     */
447    public static boolean toBoolean(final int value, final int trueValue, final int falseValue) {
448        if (value == trueValue) {
449            return true;
450        }
451        if (value == falseValue) {
452            return false;
453        }
454        throw new IllegalArgumentException("The Integer did not match either specified value");
455    }
456
457    /**
458     * Converts an Integer to a boolean specifying the conversion values.
459     *
460     * <pre>
461     *   BooleanUtils.toBoolean(Integer.valueOf(0), Integer.valueOf(1), Integer.valueOf(0)) = false
462     *   BooleanUtils.toBoolean(Integer.valueOf(1), Integer.valueOf(1), Integer.valueOf(0)) = true
463     *   BooleanUtils.toBoolean(Integer.valueOf(2), Integer.valueOf(1), Integer.valueOf(2)) = false
464     *   BooleanUtils.toBoolean(Integer.valueOf(2), Integer.valueOf(2), Integer.valueOf(0)) = true
465     *   BooleanUtils.toBoolean(null, null, Integer.valueOf(0))                     = true
466     * </pre>
467     *
468     * @param value  The Integer to convert
469     * @param trueValue  The value to match for {@code true}, may be {@code null}
470     * @param falseValue  The value to match for {@code false}, may be {@code null}
471     * @return {@code true} or {@code false}
472     * @throws IllegalArgumentException Thrown if no match.
473     */
474    public static boolean toBoolean(final Integer value, final Integer trueValue, final Integer falseValue) {
475        if (value == null) {
476            if (trueValue == null) {
477                return true;
478            }
479            if (falseValue == null) {
480                return false;
481            }
482        } else if (value.equals(trueValue)) {
483            return true;
484        } else if (value.equals(falseValue)) {
485            return false;
486        }
487        throw new IllegalArgumentException("The Integer did not match either specified value");
488    }
489
490    /**
491     * Converts a String to a boolean (optimized for performance).
492     *
493     * <p>
494     * {@code 'true'}, {@code 'on'}, {@code 'y'}, {@code 't'} or {@code 'yes'}
495     * (case insensitive) will return {@code true}. Otherwise,
496     * {@code false} is returned.
497     * </p>
498     *
499     * <p>
500     * This method performs 4 times faster (JDK1.4) than
501     * {@code Boolean.valueOf(String)}. However, this method accepts
502     * 'on' and 'yes', 't', 'y' as true values.
503     *
504     * <pre>
505     *   BooleanUtils.toBoolean(null)    = false
506     *   BooleanUtils.toBoolean("true")  = true
507     *   BooleanUtils.toBoolean("TRUE")  = true
508     *   BooleanUtils.toBoolean("tRUe")  = true
509     *   BooleanUtils.toBoolean("on")    = true
510     *   BooleanUtils.toBoolean("yes")   = true
511     *   BooleanUtils.toBoolean("false") = false
512     *   BooleanUtils.toBoolean("x gti") = false
513     *   BooleanUtils.toBoolean("y") = true
514     *   BooleanUtils.toBoolean("n") = false
515     *   BooleanUtils.toBoolean("t") = true
516     *   BooleanUtils.toBoolean("f") = false
517     * </pre>
518     *
519     * @param str  The String to check
520     * @return The boolean value of the string, {@code false} if no match or the String is null
521     */
522    public static boolean toBoolean(final String str) {
523        return toBooleanObject(str) == Boolean.TRUE;
524    }
525
526    /**
527     * Converts a String to a Boolean throwing an exception if no match found.
528     *
529     * <pre>
530     *   BooleanUtils.toBoolean("true", "true", "false")  = true
531     *   BooleanUtils.toBoolean("false", "true", "false") = false
532     * </pre>
533     *
534     * @param str  The String to check
535     * @param trueString  The String to match for {@code true} (case-sensitive), may be {@code null}
536     * @param falseString  The String to match for {@code false} (case-sensitive), may be {@code null}
537     * @return The boolean value of the string
538     * @throws IllegalArgumentException Thrown if the String doesn't match.
539     */
540    public static boolean toBoolean(final String str, final String trueString, final String falseString) {
541        if (str == trueString) {
542            return true;
543        }
544        if (str == falseString) {
545            return false;
546        }
547        if (str != null) {
548            if (str.equals(trueString)) {
549                return true;
550            }
551            if (str.equals(falseString)) {
552                return false;
553            }
554        }
555        throw new IllegalArgumentException("The String did not match either specified value");
556    }
557
558    /**
559     * Converts a Boolean to a boolean handling {@code null}.
560     *
561     * <pre>
562     *   BooleanUtils.toBooleanDefaultIfNull(Boolean.TRUE, false)  = true
563     *   BooleanUtils.toBooleanDefaultIfNull(Boolean.TRUE, true)   = true
564     *   BooleanUtils.toBooleanDefaultIfNull(Boolean.FALSE, true)  = false
565     *   BooleanUtils.toBooleanDefaultIfNull(Boolean.FALSE, false) = false
566     *   BooleanUtils.toBooleanDefaultIfNull(null, true)           = true
567     *   BooleanUtils.toBooleanDefaultIfNull(null, false)          = false
568     * </pre>
569     *
570     * @param bool  The boolean object to convert to primitive
571     * @param valueIfNull  The boolean value to return if the parameter {@code bool} is {@code null}
572     * @return {@code true} or {@code false}
573     */
574    public static boolean toBooleanDefaultIfNull(final Boolean bool, final boolean valueIfNull) {
575        if (bool == null) {
576            return valueIfNull;
577        }
578        return bool.booleanValue();
579    }
580
581    /**
582     * Converts an int to a Boolean using the convention that {@code zero}
583     * is {@code false}, everything else is {@code true}.
584     *
585     * <pre>
586     *   BooleanUtils.toBoolean(0) = Boolean.FALSE
587     *   BooleanUtils.toBoolean(1) = Boolean.TRUE
588     *   BooleanUtils.toBoolean(2) = Boolean.TRUE
589     * </pre>
590     *
591     * @param value  The int to convert
592     * @return Boolean.TRUE if non-zero, Boolean.FALSE if zero,
593     *  {@code null} if {@code null}
594     */
595    public static Boolean toBooleanObject(final int value) {
596        return value == 0 ? Boolean.FALSE : Boolean.TRUE;
597    }
598
599    /**
600     * Converts an int to a Boolean specifying the conversion values.
601     *
602     * <p>
603     * NOTE: This method may return {@code null} and may throw a {@link NullPointerException}
604     * if unboxed to a {@code boolean}.
605     * </p>
606     *
607     * <p>
608     * The checks are done first for the {@code trueValue}, then for the {@code falseValue} and
609     * finally for the {@code nullValue}.
610     * </p>
611     *
612     * <pre>
613     *   BooleanUtils.toBooleanObject(0, 0, 2, 3) = Boolean.TRUE
614     *   BooleanUtils.toBooleanObject(0, 0, 0, 3) = Boolean.TRUE
615     *   BooleanUtils.toBooleanObject(0, 0, 0, 0) = Boolean.TRUE
616     *   BooleanUtils.toBooleanObject(2, 1, 2, 3) = Boolean.FALSE
617     *   BooleanUtils.toBooleanObject(2, 1, 2, 2) = Boolean.FALSE
618     *   BooleanUtils.toBooleanObject(3, 1, 2, 3) = null
619     * </pre>
620     *
621     * @param value  The Integer to convert
622     * @param trueValue  The value to match for {@code true}
623     * @param falseValue  The value to match for {@code false}
624     * @param nullValue  The value to match for {@code null}
625     * @return Boolean.TRUE, Boolean.FALSE, or {@code null}
626     * @throws IllegalArgumentException Thrown if no match.
627     */
628    public static Boolean toBooleanObject(final int value, final int trueValue, final int falseValue, final int nullValue) {
629        if (value == trueValue) {
630            return Boolean.TRUE;
631        }
632        if (value == falseValue) {
633            return Boolean.FALSE;
634        }
635        if (value == nullValue) {
636            return null;
637        }
638        throw new IllegalArgumentException("The Integer did not match any specified value");
639    }
640
641    /**
642     * Converts an Integer to a Boolean using the convention that {@code zero}
643     * is {@code false}, every other numeric value is {@code true}.
644     *
645     * <p>
646     * {@code null} will be converted to {@code null}.
647     * </p>
648     *
649     * <p>
650     * NOTE: This method may return {@code null} and may throw a {@link NullPointerException}
651     * if unboxed to a {@code boolean}.
652     * </p>
653     *
654     * <pre>
655     *   BooleanUtils.toBooleanObject(Integer.valueOf(0))    = Boolean.FALSE
656     *   BooleanUtils.toBooleanObject(Integer.valueOf(1))    = Boolean.TRUE
657     *   BooleanUtils.toBooleanObject(Integer.valueOf(null)) = null
658     * </pre>
659     *
660     * @param value  The Integer to convert
661     * @return Boolean.TRUE if non-zero, Boolean.FALSE if zero,
662     *  {@code null} if {@code null} input
663     */
664    public static Boolean toBooleanObject(final Integer value) {
665        if (value == null) {
666            return null;
667        }
668        return value.intValue() == 0 ? Boolean.FALSE : Boolean.TRUE;
669    }
670
671    /**
672     * Converts an Integer to a Boolean specifying the conversion values.
673     *
674     * <p>
675     * NOTE: This method may return {@code null} and may throw a {@link NullPointerException}
676     * if unboxed to a {@code boolean}.
677     * </p>
678     *
679     * <p>
680     * The checks are done first for the {@code trueValue}, then for the {@code falseValue} and
681     * finally for the {@code nullValue}.
682     * </p>
683     **
684     * <pre>
685     *   BooleanUtils.toBooleanObject(Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(2), Integer.valueOf(3)) = Boolean.TRUE
686     *   BooleanUtils.toBooleanObject(Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(3)) = Boolean.TRUE
687     *   BooleanUtils.toBooleanObject(Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0)) = Boolean.TRUE
688     *   BooleanUtils.toBooleanObject(Integer.valueOf(2), Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3)) = Boolean.FALSE
689     *   BooleanUtils.toBooleanObject(Integer.valueOf(2), Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(2)) = Boolean.FALSE
690     *   BooleanUtils.toBooleanObject(Integer.valueOf(3), Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3)) = null
691     * </pre>
692     *
693     * @param value  The Integer to convert
694     * @param trueValue  The value to match for {@code true}, may be {@code null}
695     * @param falseValue  The value to match for {@code false}, may be {@code null}
696     * @param nullValue  The value to match for {@code null}, may be {@code null}
697     * @return Boolean.TRUE, Boolean.FALSE, or {@code null}
698     * @throws IllegalArgumentException Thrown if no match.
699     */
700    public static Boolean toBooleanObject(final Integer value, final Integer trueValue, final Integer falseValue, final Integer nullValue) {
701        if (value == null) {
702            if (trueValue == null) {
703                return Boolean.TRUE;
704            }
705            if (falseValue == null) {
706                return Boolean.FALSE;
707            }
708            if (nullValue == null) {
709                return null;
710            }
711        } else if (value.equals(trueValue)) {
712            return Boolean.TRUE;
713        } else if (value.equals(falseValue)) {
714            return Boolean.FALSE;
715        } else if (value.equals(nullValue)) {
716            return null;
717        }
718        throw new IllegalArgumentException("The Integer did not match any specified value");
719    }
720
721    /**
722     * Converts a String to a Boolean.
723     *
724     * <p>
725     * {@code 'true'}, {@code 'on'}, {@code 'y'}, {@code 't'}, {@code 'yes'}
726     * or {@code '1'} (case insensitive) will return {@code true}.
727     * {@code 'false'}, {@code 'off'}, {@code 'n'}, {@code 'f'}, {@code 'no'}
728     * or {@code '0'} (case insensitive) will return {@code false}.
729     * Otherwise, {@code null} is returned.
730     * </p>
731     *
732     * <p>
733     * NOTE: This method may return {@code null} and may throw a {@link NullPointerException}
734     * if unboxed to a {@code boolean}.
735     * </p>
736     *
737     * <pre>
738     *   // Case is not significant
739     *   BooleanUtils.toBooleanObject(null)    = null
740     *   BooleanUtils.toBooleanObject("true")  = Boolean.TRUE
741     *   BooleanUtils.toBooleanObject("T")     = Boolean.TRUE // i.e. T[RUE]
742     *   BooleanUtils.toBooleanObject("false") = Boolean.FALSE
743     *   BooleanUtils.toBooleanObject("f")     = Boolean.FALSE // i.e. f[alse]
744     *   BooleanUtils.toBooleanObject("No")    = Boolean.FALSE
745     *   BooleanUtils.toBooleanObject("n")     = Boolean.FALSE // i.e. n[o]
746     *   BooleanUtils.toBooleanObject("on")    = Boolean.TRUE
747     *   BooleanUtils.toBooleanObject("ON")    = Boolean.TRUE
748     *   BooleanUtils.toBooleanObject("off")   = Boolean.FALSE
749     *   BooleanUtils.toBooleanObject("oFf")   = Boolean.FALSE
750     *   BooleanUtils.toBooleanObject("yes")   = Boolean.TRUE
751     *   BooleanUtils.toBooleanObject("Y")     = Boolean.TRUE // i.e. Y[ES]
752     *   BooleanUtils.toBooleanObject("1")     = Boolean.TRUE
753     *   BooleanUtils.toBooleanObject("0")     = Boolean.FALSE
754     *   BooleanUtils.toBooleanObject("blue")  = null
755     *   BooleanUtils.toBooleanObject("true ") = null // trailing space (too long)
756     *   BooleanUtils.toBooleanObject("ono")   = null // does not match on or no
757     * </pre>
758     *
759     * @param str  The String to check; upper and lower case are treated as the same
760     * @return The Boolean value of the string, {@code null} if no match or {@code null} input
761     */
762    public static Boolean toBooleanObject(final String str) {
763        // Previously used equalsIgnoreCase, which was fast for interned 'true'.
764        // Non interned 'true' matched 15 times slower.
765        //
766        // Optimization provides same performance as before for interned 'true'.
767        // Similar performance for null, 'false', and other strings not length 2/3/4.
768        // 'true'/'TRUE' match 4 times slower, 'tRUE'/'True' 7 times slower.
769        if (str == TRUE) {
770            return Boolean.TRUE;
771        }
772        if (str == null) {
773            return null;
774        }
775        switch (str.length()) {
776            case 1: {
777                final char ch0 = str.charAt(0);
778                if (ch0 == 'y' || ch0 == 'Y' ||
779                    ch0 == 't' || ch0 == 'T' ||
780                    ch0 == '1') {
781                    return Boolean.TRUE;
782                }
783                if (ch0 == 'n' || ch0 == 'N' ||
784                    ch0 == 'f' || ch0 == 'F' ||
785                    ch0 == '0') {
786                    return Boolean.FALSE;
787                }
788                break;
789            }
790            case 2: {
791                final char ch0 = str.charAt(0);
792                final char ch1 = str.charAt(1);
793                if ((ch0 == 'o' || ch0 == 'O') &&
794                    (ch1 == 'n' || ch1 == 'N')) {
795                    return Boolean.TRUE;
796                }
797                if ((ch0 == 'n' || ch0 == 'N') &&
798                    (ch1 == 'o' || ch1 == 'O')) {
799                    return Boolean.FALSE;
800                }
801                break;
802            }
803            case 3: {
804                final char ch0 = str.charAt(0);
805                final char ch1 = str.charAt(1);
806                final char ch2 = str.charAt(2);
807                if ((ch0 == 'y' || ch0 == 'Y') &&
808                    (ch1 == 'e' || ch1 == 'E') &&
809                    (ch2 == 's' || ch2 == 'S')) {
810                    return Boolean.TRUE;
811                }
812                if ((ch0 == 'o' || ch0 == 'O') &&
813                    (ch1 == 'f' || ch1 == 'F') &&
814                    (ch2 == 'f' || ch2 == 'F')) {
815                    return Boolean.FALSE;
816                }
817                break;
818            }
819            case 4: {
820                final char ch0 = str.charAt(0);
821                final char ch1 = str.charAt(1);
822                final char ch2 = str.charAt(2);
823                final char ch3 = str.charAt(3);
824                if ((ch0 == 't' || ch0 == 'T') &&
825                    (ch1 == 'r' || ch1 == 'R') &&
826                    (ch2 == 'u' || ch2 == 'U') &&
827                    (ch3 == 'e' || ch3 == 'E')) {
828                    return Boolean.TRUE;
829                }
830                break;
831            }
832            case 5: {
833                final char ch0 = str.charAt(0);
834                final char ch1 = str.charAt(1);
835                final char ch2 = str.charAt(2);
836                final char ch3 = str.charAt(3);
837                final char ch4 = str.charAt(4);
838                if ((ch0 == 'f' || ch0 == 'F') &&
839                    (ch1 == 'a' || ch1 == 'A') &&
840                    (ch2 == 'l' || ch2 == 'L') &&
841                    (ch3 == 's' || ch3 == 'S') &&
842                    (ch4 == 'e' || ch4 == 'E')) {
843                    return Boolean.FALSE;
844                }
845                break;
846            }
847        default:
848            break;
849        }
850
851        return null;
852    }
853
854    /**
855     * Converts a String to a Boolean throwing an exception if no match.
856     *
857     * <p>
858     * NOTE: This method may return {@code null} and may throw a {@link NullPointerException}
859     * if unboxed to a {@code boolean}.
860     * </p>
861     *
862     * <pre>
863     *   BooleanUtils.toBooleanObject("true", "true", "false", "null")   = Boolean.TRUE
864     *   BooleanUtils.toBooleanObject(null, null, "false", "null")       = Boolean.TRUE
865     *   BooleanUtils.toBooleanObject(null, null, null, "null")          = Boolean.TRUE
866     *   BooleanUtils.toBooleanObject(null, null, null, null)            = Boolean.TRUE
867     *   BooleanUtils.toBooleanObject("false", "true", "false", "null")  = Boolean.FALSE
868     *   BooleanUtils.toBooleanObject("false", "true", "false", "false") = Boolean.FALSE
869     *   BooleanUtils.toBooleanObject(null, "true", null, "false")       = Boolean.FALSE
870     *   BooleanUtils.toBooleanObject(null, "true", null, null)          = Boolean.FALSE
871     *   BooleanUtils.toBooleanObject("null", "true", "false", "null")   = null
872     * </pre>
873     *
874     * @param str  The String to check
875     * @param trueString  The String to match for {@code true} (case-sensitive), may be {@code null}
876     * @param falseString  The String to match for {@code false} (case-sensitive), may be {@code null}
877     * @param nullString  The String to match for {@code null} (case-sensitive), may be {@code null}
878     * @return The Boolean value of the string, {@code null} if either the String matches {@code nullString}
879     *  or if {@code null} input and {@code nullString} is {@code null}
880     * @throws IllegalArgumentException Thrown if the String doesn't match.
881     */
882    public static Boolean toBooleanObject(final String str, final String trueString, final String falseString, final String nullString) {
883        if (str == null) {
884            if (trueString == null) {
885                return Boolean.TRUE;
886            }
887            if (falseString == null) {
888                return Boolean.FALSE;
889            }
890            if (nullString == null) {
891                return null;
892            }
893        } else if (str.equals(trueString)) {
894            return Boolean.TRUE;
895        } else if (str.equals(falseString)) {
896            return Boolean.FALSE;
897        } else if (str.equals(nullString)) {
898            return null;
899        }
900        // no match
901        throw new IllegalArgumentException("The String did not match any specified value");
902    }
903
904    /**
905     * Converts a boolean to an int using the convention that
906     * {@code true} is {@code 1} and {@code false} is {@code 0}.
907     *
908     * <pre>
909     *   BooleanUtils.toInteger(true)  = 1
910     *   BooleanUtils.toInteger(false) = 0
911     * </pre>
912     *
913     * @param bool  The boolean to convert
914     * @return one if {@code true}, zero if {@code false}
915     */
916    public static int toInteger(final boolean bool) {
917        return bool ? 1 : 0;
918    }
919
920    /**
921     * Converts a boolean to an int specifying the conversion values.
922     *
923     * <pre>
924     *   BooleanUtils.toInteger(true, 1, 0)  = 1
925     *   BooleanUtils.toInteger(false, 1, 0) = 0
926     * </pre>
927     *
928     * @param bool  The to convert
929     * @param trueValue  The value to return if {@code true}
930     * @param falseValue  The value to return if {@code false}
931     * @return The appropriate value
932     */
933    public static int toInteger(final boolean bool, final int trueValue, final int falseValue) {
934        return bool ? trueValue : falseValue;
935    }
936
937    /**
938     * Converts a Boolean to an int specifying the conversion values.
939     *
940     * <pre>
941     *   BooleanUtils.toInteger(Boolean.TRUE, 1, 0, 2)  = 1
942     *   BooleanUtils.toInteger(Boolean.FALSE, 1, 0, 2) = 0
943     *   BooleanUtils.toInteger(null, 1, 0, 2)          = 2
944     * </pre>
945     *
946     * @param bool  The Boolean to convert
947     * @param trueValue  The value to return if {@code true}
948     * @param falseValue  The value to return if {@code false}
949     * @param nullValue  The value to return if {@code null}
950     * @return The appropriate value
951     */
952    public static int toInteger(final Boolean bool, final int trueValue, final int falseValue, final int nullValue) {
953        if (bool == null) {
954            return nullValue;
955        }
956        return bool.booleanValue() ? trueValue : falseValue;
957    }
958
959    /**
960     * Converts a boolean to an Integer using the convention that
961     * {@code true} is {@code 1} and {@code false} is {@code 0}.
962     *
963     * <pre>
964     *   BooleanUtils.toIntegerObject(true)  = Integer.valueOf(1)
965     *   BooleanUtils.toIntegerObject(false) = Integer.valueOf(0)
966     * </pre>
967     *
968     * @param bool  The boolean to convert
969     * @return one if {@code true}, zero if {@code false}
970     */
971    public static Integer toIntegerObject(final boolean bool) {
972        return bool ? NumberUtils.INTEGER_ONE : NumberUtils.INTEGER_ZERO;
973    }
974
975    /**
976     * Converts a boolean to an Integer specifying the conversion values.
977     *
978     * <pre>
979     *   BooleanUtils.toIntegerObject(true, Integer.valueOf(1), Integer.valueOf(0))  = Integer.valueOf(1)
980     *   BooleanUtils.toIntegerObject(false, Integer.valueOf(1), Integer.valueOf(0)) = Integer.valueOf(0)
981     * </pre>
982     *
983     * @param bool  The to convert
984     * @param trueValue  The value to return if {@code true}, may be {@code null}
985     * @param falseValue  The value to return if {@code false}, may be {@code null}
986     * @return The appropriate value
987     */
988    public static Integer toIntegerObject(final boolean bool, final Integer trueValue, final Integer falseValue) {
989        return bool ? trueValue : falseValue;
990    }
991
992    /**
993     * Converts a Boolean to an Integer using the convention that
994     * {@code zero} is {@code false}.
995     *
996     * <p>
997     * {@code null} will be converted to {@code null}.
998     * </p>
999     *
1000     * <pre>
1001     *   BooleanUtils.toIntegerObject(Boolean.TRUE)  = Integer.valueOf(1)
1002     *   BooleanUtils.toIntegerObject(Boolean.FALSE) = Integer.valueOf(0)
1003     * </pre>
1004     *
1005     * @param bool  The Boolean to convert
1006     * @return one if Boolean.TRUE, zero if Boolean.FALSE, {@code null} if {@code null}
1007     */
1008    public static Integer toIntegerObject(final Boolean bool) {
1009        if (bool == null) {
1010            return null;
1011        }
1012        return bool.booleanValue() ? NumberUtils.INTEGER_ONE : NumberUtils.INTEGER_ZERO;
1013    }
1014
1015    /**
1016     * Converts a Boolean to an Integer specifying the conversion values.
1017     *
1018     * <pre>
1019     *   BooleanUtils.toIntegerObject(Boolean.TRUE, Integer.valueOf(1), Integer.valueOf(0), Integer.valueOf(2))  = Integer.valueOf(1)
1020     *   BooleanUtils.toIntegerObject(Boolean.FALSE, Integer.valueOf(1), Integer.valueOf(0), Integer.valueOf(2)) = Integer.valueOf(0)
1021     *   BooleanUtils.toIntegerObject(null, Integer.valueOf(1), Integer.valueOf(0), Integer.valueOf(2))          = Integer.valueOf(2)
1022     * </pre>
1023     *
1024     * @param bool  The Boolean to convert
1025     * @param trueValue  The value to return if {@code true}, may be {@code null}
1026     * @param falseValue  The value to return if {@code false}, may be {@code null}
1027     * @param nullValue  The value to return if {@code null}, may be {@code null}
1028     * @return The appropriate value
1029     */
1030    public static Integer toIntegerObject(final Boolean bool, final Integer trueValue, final Integer falseValue, final Integer nullValue) {
1031        if (bool == null) {
1032            return nullValue;
1033        }
1034        return bool.booleanValue() ? trueValue : falseValue;
1035    }
1036
1037    /**
1038     * Converts a boolean to a String returning one of the input Strings.
1039     *
1040     * <pre>
1041     *   BooleanUtils.toString(true, "true", "false")   = "true"
1042     *   BooleanUtils.toString(false, "true", "false")  = "false"
1043     * </pre>
1044     *
1045     * @param bool  The Boolean to check
1046     * @param trueString  The String to return if {@code true}, may be {@code null}
1047     * @param falseString  The String to return if {@code false}, may be {@code null}
1048     * @return one of the two input Strings
1049     */
1050    public static String toString(final boolean bool, final String trueString, final String falseString) {
1051        return bool ? trueString : falseString;
1052    }
1053
1054    /**
1055     * Converts a Boolean to a String returning one of the input Strings.
1056     *
1057     * <pre>
1058     *   BooleanUtils.toString(Boolean.TRUE, "true", "false", null)   = "true"
1059     *   BooleanUtils.toString(Boolean.FALSE, "true", "false", null)  = "false"
1060     *   BooleanUtils.toString(null, "true", "false", null)           = null;
1061     * </pre>
1062     *
1063     * @param bool  The Boolean to check
1064     * @param trueString  The String to return if {@code true}, may be {@code null}
1065     * @param falseString  The String to return if {@code false}, may be {@code null}
1066     * @param nullString  The String to return if {@code null}, may be {@code null}
1067     * @return one of the three input Strings
1068     */
1069    public static String toString(final Boolean bool, final String trueString, final String falseString, final String nullString) {
1070        if (bool == null) {
1071            return nullString;
1072        }
1073        return bool.booleanValue() ? trueString : falseString;
1074    }
1075
1076    /**
1077     * Converts a boolean to a String returning {@code 'on'}
1078     * or {@code 'off'}.
1079     *
1080     * <pre>
1081     *   BooleanUtils.toStringOnOff(true)   = "on"
1082     *   BooleanUtils.toStringOnOff(false)  = "off"
1083     * </pre>
1084     *
1085     * @param bool  The Boolean to check
1086     * @return {@code 'on'}, {@code 'off'}, or {@code null}
1087     */
1088    public static String toStringOnOff(final boolean bool) {
1089        return toString(bool, ON, OFF);
1090    }
1091
1092    /**
1093     * Converts a Boolean to a String returning {@code 'on'},
1094     * {@code 'off'}, or {@code null}.
1095     *
1096     * <pre>
1097     *   BooleanUtils.toStringOnOff(Boolean.TRUE)  = "on"
1098     *   BooleanUtils.toStringOnOff(Boolean.FALSE) = "off"
1099     *   BooleanUtils.toStringOnOff(null)          = null;
1100     * </pre>
1101     *
1102     * @param bool  The Boolean to check
1103     * @return {@code 'on'}, {@code 'off'}, or {@code null}
1104     */
1105    public static String toStringOnOff(final Boolean bool) {
1106        return toString(bool, ON, OFF, null);
1107    }
1108
1109    /**
1110     * Converts a boolean to a String returning {@code 'true'}
1111     * or {@code 'false'}.
1112     *
1113     * <pre>
1114     *   BooleanUtils.toStringTrueFalse(true)   = "true"
1115     *   BooleanUtils.toStringTrueFalse(false)  = "false"
1116     * </pre>
1117     *
1118     * @param bool  The Boolean to check
1119     * @return {@code 'true'}, {@code 'false'}, or {@code null}
1120     */
1121    public static String toStringTrueFalse(final boolean bool) {
1122        return toString(bool, TRUE, FALSE);
1123    }
1124
1125    /**
1126     * Converts a Boolean to a String returning {@code 'true'},
1127     * {@code 'false'}, or {@code null}.
1128     *
1129     * <pre>
1130     *   BooleanUtils.toStringTrueFalse(Boolean.TRUE)  = "true"
1131     *   BooleanUtils.toStringTrueFalse(Boolean.FALSE) = "false"
1132     *   BooleanUtils.toStringTrueFalse(null)          = null;
1133     * </pre>
1134     *
1135     * @param bool  The Boolean to check
1136     * @return {@code 'true'}, {@code 'false'}, or {@code null}
1137     */
1138    public static String toStringTrueFalse(final Boolean bool) {
1139        return toString(bool, TRUE, FALSE, null);
1140    }
1141
1142    /**
1143     * Converts a boolean to a String returning {@code 'yes'}
1144     * or {@code 'no'}.
1145     *
1146     * <pre>
1147     *   BooleanUtils.toStringYesNo(true)   = "yes"
1148     *   BooleanUtils.toStringYesNo(false)  = "no"
1149     * </pre>
1150     *
1151     * @param bool  The Boolean to check
1152     * @return {@code 'yes'}, {@code 'no'}, or {@code null}
1153     */
1154    public static String toStringYesNo(final boolean bool) {
1155        return toString(bool, YES, NO);
1156    }
1157
1158    /**
1159     * Converts a Boolean to a String returning {@code 'yes'},
1160     * {@code 'no'}, or {@code null}.
1161     *
1162     * <pre>
1163     *   BooleanUtils.toStringYesNo(Boolean.TRUE)  = "yes"
1164     *   BooleanUtils.toStringYesNo(Boolean.FALSE) = "no"
1165     *   BooleanUtils.toStringYesNo(null)          = null;
1166     * </pre>
1167     *
1168     * @param bool  The Boolean to check
1169     * @return {@code 'yes'}, {@code 'no'}, or {@code null}
1170     */
1171    public static String toStringYesNo(final Boolean bool) {
1172        return toString(bool, YES, NO, null);
1173    }
1174
1175    /**
1176     * Returns an unmodifiable list of Booleans {@code [false, true]}.
1177     *
1178     * @return An unmodifiable list of Booleans {@code [false, true]}.
1179     * @since 3.13.0
1180     */
1181    public static List<Boolean> values() {
1182        return BOOLEAN_LIST;
1183    }
1184
1185    /**
1186     * Performs an xor on a set of booleans.
1187     * <p>
1188     *   This behaves like an XOR gate;
1189     *   it returns true if the number of true values is odd,
1190     *   and false if the number of true values is zero or even.
1191     * </p>
1192     *
1193     * <pre>
1194     *   BooleanUtils.xor(true, true)             = false
1195     *   BooleanUtils.xor(false, false)           = false
1196     *   BooleanUtils.xor(true, false)            = true
1197     *   BooleanUtils.xor(true, false, false)     = true
1198     *   BooleanUtils.xor(true, true, true)       = true
1199     *   BooleanUtils.xor(true, true, true, true) = false
1200     * </pre>
1201     *
1202     * @param array  An array of {@code boolean}s
1203     * @return true if the number of true values in the array is odd; otherwise returns false.
1204     * @throws NullPointerException Thrown if {@code array} is {@code null}.
1205     * @throws IllegalArgumentException Thrown if {@code array} is empty.
1206     */
1207    public static boolean xor(final boolean... array) {
1208        ObjectUtils.requireNonEmpty(array, "array");
1209        // false if the neutral element of the xor operator
1210        boolean result = false;
1211        for (final boolean element : array) {
1212            result ^= element;
1213        }
1214
1215        return result;
1216    }
1217
1218    /**
1219     * Performs an xor on an array of Booleans.
1220     * <pre>
1221     *   BooleanUtils.xor(Boolean.TRUE, Boolean.TRUE)                 = Boolean.FALSE
1222     *   BooleanUtils.xor(Boolean.FALSE, Boolean.FALSE)               = Boolean.FALSE
1223     *   BooleanUtils.xor(Boolean.TRUE, Boolean.FALSE)                = Boolean.TRUE
1224     *   BooleanUtils.xor(Boolean.TRUE, Boolean.FALSE, Boolean.FALSE) = Boolean.TRUE
1225     *   BooleanUtils.xor(Boolean.FALSE, null)                        = Boolean.FALSE
1226     *   BooleanUtils.xor(Boolean.TRUE, null)                         = Boolean.TRUE
1227     * </pre>
1228     * <p>
1229     * Null array elements map to false, like {@code Boolean.parseBoolean(null)} and its callers return false.
1230     * </p>
1231     *
1232     * @param array  An array of {@link Boolean}s
1233     * @return The result of the xor operations
1234     * @throws NullPointerException Thrown if {@code array} is {@code null}.
1235     * @throws IllegalArgumentException Thrown if {@code array} is empty.
1236     */
1237    public static Boolean xor(final Boolean... array) {
1238        ObjectUtils.requireNonEmpty(array, "array");
1239        return xor(ArrayUtils.toPrimitive(array)) ? Boolean.TRUE : Boolean.FALSE;
1240    }
1241
1242    /**
1243     * {@link BooleanUtils} instances should NOT be constructed in standard programming.
1244     * Instead, the class should be used as {@code BooleanUtils.negate(true);}.
1245     *
1246     * <p>
1247     * This constructor is public to permit tools that require a JavaBean instance
1248     * to operate.
1249     * </p>
1250     *
1251     * @deprecated TODO Make private in 4.0.
1252     */
1253    @Deprecated
1254    public BooleanUtils() {
1255        // empty
1256    }
1257
1258}