// Path: send-notification/src/main/java/fr/jcgay/notification/DiscoverableNotifier.java
// public interface DiscoverableNotifier extends Notifier {
// 
//     /**
//      * Initialize before usage. <br>
//      * This method must be called before trying to send a notification. <br>
//      * Calling {@code init()} multiple time should not fail. <br>
//      *
//      * For example a notifier can open a connection to register the application, or it can do nothing.
//      *
//      * @return a usable initiated {@link Notifier} to send notification(s)
//      * @throws fr.jcgay.notification.SendNotificationException when something fails.
//      */
//     Notifier init();
// 
//     boolean tryInit();
// }
// 
// Path: send-notification/src/main/java/fr/jcgay/notification/MultipleSendNotificationException.java
// public class MultipleSendNotificationException extends SendNotificationException {
// 
//     private List<Exception> errors;
// 
//     public MultipleSendNotificationException(List<Exception> errors) {
//         super(messages(checkNotNull(errors)));
//         this.errors = errors;
//     }
// 
//     public List<Exception> getErrors() {
//         return Collections.unmodifiableList(errors);
//     }
// 
//     private static String messages(List<Exception> errors) {
//         Iterator<Exception> iterator = errors.iterator();
//         StringBuilder messages = new StringBuilder(iterator.next().getMessage());
//         while (iterator.hasNext()) {
//             Exception error = iterator.next();
//             if (error.getMessage() != null) {
//                 messages.append(String.format("%n%s", error.getMessage()));
//             }
//         }
//         return messages.toString();
//     }
// }
// 
// Path: send-notification/src/main/java/fr/jcgay/notification/Notification.java
// @AutoValue
// public abstract class Notification {
// 
//     /**
//      * Indicate notification priority.
//      */
//     public enum Level {INFO, WARNING, ERROR}
// 
//     /**
//      * Notification message.
//      *
//      * @return message.
//      */
//     public abstract String message();
// 
//     /**
//      * Notification title.
//      *
//      * @return title.
//      */
//     public abstract String title();
// 
//     /**
//      * Notification subtitle. <br>
//      * Not available for all notifier implementation.
//      *
//      * @return subtitle.
//      */
//     @Nullable
//     public abstract String subtitle();
// 
//     /**
//      * Notification icon.
//      *
//      * @return icon.
//      */
//     public abstract Icon icon();
// 
//     /**
//      * Indicate the notification priority type.
//      *
//      * @return type
//      */
//     public abstract Level level();
// 
//     Notification() {
//         // prevent external subclasses
//     }
// 
//     public static Builder builder(String title, String message, Icon icon) {
//         return builder()
//             .title(title)
//             .message(message)
//             .icon(icon);
//     }
// 
//     public static Builder builder() {
//         return new AutoValue_Notification.Builder().level(INFO);
//     }
// 
//     @AutoValue.Builder
//     public interface Builder {
//         Builder title(String title);
//         Builder message(String message);
//         Builder icon(Icon icon);
//         Builder subtitle(String subtitle);
//         Builder level(Level level);
//         Notification build();
//     }
// }
// 
// Path: send-notification/src/main/java/fr/jcgay/notification/Notifier.java
// public interface Notifier {
// 
//     /**
//      * Send a notification.
//      *
//      * @param notification a notification.
//      *
//      * @throws fr.jcgay.notification.SendNotificationException when something fails.
//      */
//     void send(Notification notification);
// 
//     /**
//      * Close the notifier. <br>
//      * This method must be called to release resources when the notifier is not needed anymore.
//      */
//     void close();
// 
//     /**
//      * Indicate if the notifier is always displayed somewhere (menu/task bar, etc).
//      * @return {@code true} if the notifier is persistent.
//      */
//     boolean isPersistent();
// }


import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import fr.jcgay.notification.DiscoverableNotifier;
import fr.jcgay.notification.MultipleSendNotificationException;
import fr.jcgay.notification.Notification;
import fr.jcgay.notification.Notifier;
import org.slf4j.Logger;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
    public void send(Notification notification) {
        List<Exception> errors = new ArrayList<>();

        safeSend(primary, notification, errors);

        if (notifyWithSecondaryNotifiers) {
            for (DiscoverableNotifier notifier : secondary) {
                safeSend(notifier, notification, errors);
            }
        }

        failIfNotEmpty(errors);
    }

    @Override
    public void close() {
        List<Exception> errors = new ArrayList<>();

        safeClose(primary, errors);

        if (notifyWithSecondaryNotifiers) {
            for (DiscoverableNotifier notifier : secondary) {
                safeClose(notifier, errors);
            }
        }

        failIfNotEmpty(errors);
    }

    @Override
// Path: send-notification/src/main/java/fr/jcgay/notification/DiscoverableNotifier.java
// public interface DiscoverableNotifier extends Notifier {
// 
//     /**
//      * Initialize before usage. <br>
//      * This method must be called before trying to send a notification. <br>
//      * Calling {@code init()} multiple time should not fail. <br>
//      *
//      * For example a notifier can open a connection to register the application, or it can do nothing.
//      *
//      * @return a usable initiated {@link Notifier} to send notification(s)
//      * @throws fr.jcgay.notification.SendNotificationException when something fails.
//      */
//     Notifier init();
// 
//     boolean tryInit();
// }
// 
// Path: send-notification/src/main/java/fr/jcgay/notification/MultipleSendNotificationException.java
// public class MultipleSendNotificationException extends SendNotificationException {
// 
//     private List<Exception> errors;
// 
//     public MultipleSendNotificationException(List<Exception> errors) {
//         super(messages(checkNotNull(errors)));
//         this.errors = errors;
//     }
// 
//     public List<Exception> getErrors() {
//         return Collections.unmodifiableList(errors);
//     }
// 
//     private static String messages(List<Exception> errors) {
//         Iterator<Exception> iterator = errors.iterator();
//         StringBuilder messages = new StringBuilder(iterator.next().getMessage());
//         while (iterator.hasNext()) {
//             Exception error = iterator.next();
//             if (error.getMessage() != null) {
//                 messages.append(String.format("%n%s", error.getMessage()));
//             }
//         }
//         return messages.toString();
//     }
// }
// 
// Path: send-notification/src/main/java/fr/jcgay/notification/Notification.java
// @AutoValue
// public abstract class Notification {
// 
//     /**
//      * Indicate notification priority.
//      */
//     public enum Level {INFO, WARNING, ERROR}
// 
//     /**
//      * Notification message.
//      *
//      * @return message.
//      */
//     public abstract String message();
// 
//     /**
//      * Notification title.
//      *
//      * @return title.
//      */
//     public abstract String title();
// 
//     /**
//      * Notification subtitle. <br>
//      * Not available for all notifier implementation.
//      *
//      * @return subtitle.
//      */
//     @Nullable
//     public abstract String subtitle();
// 
//     /**
//      * Notification icon.
//      *
//      * @return icon.
//      */
//     public abstract Icon icon();
// 
//     /**
//      * Indicate the notification priority type.
//      *
//      * @return type
//      */
//     public abstract Level level();
// 
//     Notification() {
//         // prevent external subclasses
//     }
// 
//     public static Builder builder(String title, String message, Icon icon) {
//         return builder()
//             .title(title)
//             .message(message)
//             .icon(icon);
//     }
// 
//     public static Builder builder() {
//         return new AutoValue_Notification.Builder().level(INFO);
//     }
// 
//     @AutoValue.Builder
//     public interface Builder {
//         Builder title(String title);
//         Builder message(String message);
//         Builder icon(Icon icon);
//         Builder subtitle(String subtitle);
//         Builder level(Level level);
//         Notification build();
//     }
// }
// 
// Path: send-notification/src/main/java/fr/jcgay/notification/Notifier.java
// public interface Notifier {
// 
//     /**
//      * Send a notification.
//      *
//      * @param notification a notification.
//      *
//      * @throws fr.jcgay.notification.SendNotificationException when something fails.
//      */
//     void send(Notification notification);
// 
//     /**
//      * Close the notifier. <br>
//      * This method must be called to release resources when the notifier is not needed anymore.
//      */
//     void close();
// 
//     /**
//      * Indicate if the notifier is always displayed somewhere (menu/task bar, etc).
//      * @return {@code true} if the notifier is persistent.
//      */
//     boolean isPersistent();
// }


// Path: send-notification/src/main/java/fr/jcgay/notification/notifier/additional/AdditionalNotifier.java
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import fr.jcgay.notification.DiscoverableNotifier;
import fr.jcgay.notification.MultipleSendNotificationException;
import fr.jcgay.notification.Notification;
import fr.jcgay.notification.Notifier;
import org.slf4j.Logger;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;

    public void send(Notification notification) {
        List<Exception> errors = new ArrayList<>();

        safeSend(primary, notification, errors);

        if (notifyWithSecondaryNotifiers) {
            for (DiscoverableNotifier notifier : secondary) {
                safeSend(notifier, notification, errors);
            }
        }

        failIfNotEmpty(errors);
    }

    @Override
    public void close() {
        List<Exception> errors = new ArrayList<>();

        safeClose(primary, errors);

        if (notifyWithSecondaryNotifiers) {
            for (DiscoverableNotifier notifier : secondary) {
                safeClose(notifier, errors);
            }
        }

        failIfNotEmpty(errors);
    }

    @Override
    public boolean isPersistent() {