// 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/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/executor/Executor.java
// public interface Executor {
//     void exec(String[] command);
//     boolean tryExec(String[] command);
//     void close();
// }


import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import fr.jcgay.notification.DiscoverableNotifier;
import fr.jcgay.notification.Notification;
import fr.jcgay.notification.Notifier;
import fr.jcgay.notification.notifier.executor.Executor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
            throw new ToasterNotificationException("Error while sending notification with toaster", e);
        }
    }

    @Override
    public void close() {
        executor.close();
    }

    @Override
    public boolean isPersistent() {
        return false;
    }

    @Override
    public boolean tryInit() {
        List<String> commands = new ArrayList<>();
        commands.add(configuration.bin());

        return executor.tryExec(commands.toArray(new String[0]));
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(configuration);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
// 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/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/executor/Executor.java
// public interface Executor {
//     void exec(String[] command);
//     boolean tryExec(String[] command);
//     void close();
// }


// Path: send-notification/src/main/java/fr/jcgay/notification/notifier/toaster/ToasterNotifier.java
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import fr.jcgay.notification.DiscoverableNotifier;
import fr.jcgay.notification.Notification;
import fr.jcgay.notification.Notifier;
import fr.jcgay.notification.notifier.executor.Executor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;

            throw new ToasterNotificationException("Error while sending notification with toaster", e);
        }
    }

    @Override
    public void close() {
        executor.close();
    }

    @Override
    public boolean isPersistent() {
        return false;
    }

    @Override
    public boolean tryInit() {
        List<String> commands = new ArrayList<>();
        commands.add(configuration.bin());

        return executor.tryExec(commands.toArray(new String[0]));
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(configuration);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;