/*
 *
 * Copyright (c) 2006-2019, Speedment, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); You may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.speedment.common.function;

import java.util.NoSuchElementException;
import java.util.function.Supplier;

import static java.util.Objects.requireNonNull;

/**
 * An {@code Optional} specialized for primitive boolean values.
 * 
 * @author  Emil Forslund
 * @since   1.0.0
 */
public enum OptionalBoolean {
    
    FALSE, TRUE, EMPTY;
    
    public static OptionalBoolean empty() {
        return EMPTY;
    }
    
    public static OptionalBoolean of(boolean bool) {
        return bool ? TRUE : FALSE;
    }
    
    public static OptionalBoolean ofNullable(Boolean bool) {
        if (bool == null) {
            return empty();
        } else {
            return of(bool);
        }
    }

    /**
     * If a value is present, and the value matches the given predicate,
     * return a {@code BooleanOptional} describing the value, otherwise return an
     * empty {@code BooleanOptional}.
     *
     * @param predicate a predicate to apply to the value, if present
     * @return a {@code BooleanOptional} describing the value of this {@code BooleanOptional}
     * if a value is present and the value matches the given predicate,
     * otherwise an empty {@code BooleanOptional}
     * @throws NullPointerException if the predicate is null
     */
    public OptionalBoolean filter(BooleanPredicate predicate) {
        requireNonNull(predicate);
        if (!isPresent())
            return this;
        else
            return predicate.test(this == TRUE) ? this : empty();
    }
    
    public boolean getAsBoolean() {
        switch (this) {
            case FALSE : return false;
            case TRUE  : return true;
            default :
                throw new NoSuchElementException(
                    "Attempted to get value from empty OptionalBoolean."
                );
        }
    }
    
    public boolean orElse(boolean ifEmpty) {
        switch (this) {
            case FALSE : return false;
            case TRUE  : return true;
            default    : return ifEmpty;
        }
    }
    
    public <T extends Throwable> boolean orElseThrow(Supplier<T> thrower) throws T {
        switch (this) {
            case FALSE : return false;
            case TRUE  : return true;
            default    : throw thrower.get();
        }
    }
    
    public boolean isPresent() {
        return this != EMPTY;
    }
    
    public void ifPresent(BooleanConsumer consumer) {
        switch (this) {
            case FALSE : { consumer.accept(false); break;}
            case TRUE  : { consumer.accept(true); break;}
            default: // do nothing
        }
    }
}
@@ -3100,147 +3100,336 @@
  : %7B
- consumer.accept(false); break;%7D%0A            case TRUE  : %7B consumer.accept(true); break;%7D%0A            default: // do nothing%0A        %7D%0A    %7D
+%0A                acceptConsumer(consumer, false);%0A                break;%7D%0A            case TRUE  : %7B%0A                acceptConsumer(consumer, true);%0A                break;%7D%0A            default: // do nothing%0A        %7D%0A    %7D%0A%0A    private void acceptConsumer(BooleanConsumer consumer, boolean b) %7B%0A        consumer.accept(b);%0A    %7D%0A
 %0A%7D

Resolve SQ issues