// Path: src/main/java/com/mb3364/twitch/api/auth/Scopes.java
// public enum Scopes {
// 
//     /**
//      * Read access to non-public user information, such as email address.
//      */
//     USER_READ("user_read"),
// 
//     /**
//      * Ability to ignore or unignore on behalf of a user.
//      */
//     USER_BLOCKS_EDIT("user_blocks_edit"),
// 
//     /**
//      * Read access to a user's list of ignored users.
//      */
//     USER_BLOCKS_READ("user_blocks_read"),
// 
//     /**
//      * Access to manage a user's followed channels.
//      */
//     USER_FOLLOWS_EDIT("user_follows_edit"),
// 
//     /**
//      * Read access to non-public channel information, including email address and stream key.
//      */
//     CHANNEL_READ("channel_read"),
// 
//     /**
//      * Write access to channel metadata (game, status, etc).
//      */
//     CHANNEL_EDITOR("channel_editor"),
// 
//     /**
//      * Access to trigger commercials on channel.
//      */
//     CHANNEL_COMMERCIAL("channel_commercial"),
// 
//     /**
//      * Ability to reset a channel's stream key.
//      */
//     CHANNEL_STREAM("channel_stream"),
// 
//     /**
//      * Read access to all subscribers to your channel.
//      */
//     CHANNEL_SUBSCRIPTIONS("channel_subscriptions"),
// 
//     /**
//      * Read access to subscriptions of a user.
//      */
//     USER_SUBSCRIPTIONS("user_subscriptions"),
// 
//     /**
//      * Read access to check if a user is subscribed to your channel.
//      */
//     CHANNEL_CHECK_SUBSCRIPTION("channel_check_subscription"),
// 
//     /**
//      * Ability to log into chat and send messages.
//      */
//     CHAT_LOGIN("chat_login");
// 
//     private String key;
// 
//     Scopes(String key) {
//         this.key = key;
//     }
// 
//     /**
//      * Combine <code>Scopes</code> into a '+' separated <code>String</code>.
//      * This is the required input format for twitch.tv
//      *
//      * @param scopes <code>Scopes</code> to combine.
//      * @return <code>String</code> representing '+' separated list of <code>Scopes</code>
//      */
//     public static String join(Scopes... scopes) {
//         if (scopes == null) return "";
//         StringBuilder sb = new StringBuilder();
//         for (Scopes scope : scopes) {
//             sb.append(scope.getKey()).append("+");
//         }
//         return sb.toString();
//     }
// 
//     /**
//      * Convert the string representation of the Scope to the Enum.
//      *
//      * @param text Text representation of Enum value
//      * @return Enum value that the text represents
//      */
//     public static Scopes fromString(String text) {
//         if (text == null) return null;
//         for (Scopes b : Scopes.values()) {
//             if (text.equalsIgnoreCase(b.key)) {
//                 return b;
//             }
//         }
//         return null;
//     }
// 
//     /**
//      * Get the identifier that twitch will recognize.
//      *
//      * @return A <code>String</code> identifier
//      */
//     public String getKey() {
//         return key;
//     }
// 
//     @Override
//     public String toString() {
//         return key;
//     }
// }


import com.mb3364.twitch.api.auth.Scopes;
import java.io.IOException;
import java.net.*;
        return serverSocket != null;
    }

    @Override
    public void onAccessTokenReceived(String token, Scopes... scopes) {
        accessToken = token;
        accessScopes = scopes;
        stop(); // Stop the server, we no longer need to process requests
    }

    @Override
    public void onAuthenticationError(String error, String description) {
        authenticationError = new AuthenticationError(error, description);
        stop(); // Stop the server
    }

    /**
     * Get the access token if one exists.
     *
     * @return Access token if it exists, <code>null</code> otherwise
     */
    public String getAccessToken() {
        return accessToken;
    }

    /**
     * Get the access scopes for the authenticated user.
     *
     * @return Array of {@link Scopes} that the authenticated user has
     */
// Path: src/main/java/com/mb3364/twitch/api/auth/Scopes.java
// public enum Scopes {
// 
//     /**
//      * Read access to non-public user information, such as email address.
//      */
//     USER_READ("user_read"),
// 
//     /**
//      * Ability to ignore or unignore on behalf of a user.
//      */
//     USER_BLOCKS_EDIT("user_blocks_edit"),
// 
//     /**
//      * Read access to a user's list of ignored users.
//      */
//     USER_BLOCKS_READ("user_blocks_read"),
// 
//     /**
//      * Access to manage a user's followed channels.
//      */
//     USER_FOLLOWS_EDIT("user_follows_edit"),
// 
//     /**
//      * Read access to non-public channel information, including email address and stream key.
//      */
//     CHANNEL_READ("channel_read"),
// 
//     /**
//      * Write access to channel metadata (game, status, etc).
//      */
//     CHANNEL_EDITOR("channel_editor"),
// 
//     /**
//      * Access to trigger commercials on channel.
//      */
//     CHANNEL_COMMERCIAL("channel_commercial"),
// 
//     /**
//      * Ability to reset a channel's stream key.
//      */
//     CHANNEL_STREAM("channel_stream"),
// 
//     /**
//      * Read access to all subscribers to your channel.
//      */
//     CHANNEL_SUBSCRIPTIONS("channel_subscriptions"),
// 
//     /**
//      * Read access to subscriptions of a user.
//      */
//     USER_SUBSCRIPTIONS("user_subscriptions"),
// 
//     /**
//      * Read access to check if a user is subscribed to your channel.
//      */
//     CHANNEL_CHECK_SUBSCRIPTION("channel_check_subscription"),
// 
//     /**
//      * Ability to log into chat and send messages.
//      */
//     CHAT_LOGIN("chat_login");
// 
//     private String key;
// 
//     Scopes(String key) {
//         this.key = key;
//     }
// 
//     /**
//      * Combine <code>Scopes</code> into a '+' separated <code>String</code>.
//      * This is the required input format for twitch.tv
//      *
//      * @param scopes <code>Scopes</code> to combine.
//      * @return <code>String</code> representing '+' separated list of <code>Scopes</code>
//      */
//     public static String join(Scopes... scopes) {
//         if (scopes == null) return "";
//         StringBuilder sb = new StringBuilder();
//         for (Scopes scope : scopes) {
//             sb.append(scope.getKey()).append("+");
//         }
//         return sb.toString();
//     }
// 
//     /**
//      * Convert the string representation of the Scope to the Enum.
//      *
//      * @param text Text representation of Enum value
//      * @return Enum value that the text represents
//      */
//     public static Scopes fromString(String text) {
//         if (text == null) return null;
//         for (Scopes b : Scopes.values()) {
//             if (text.equalsIgnoreCase(b.key)) {
//                 return b;
//             }
//         }
//         return null;
//     }
// 
//     /**
//      * Get the identifier that twitch will recognize.
//      *
//      * @return A <code>String</code> identifier
//      */
//     public String getKey() {
//         return key;
//     }
// 
//     @Override
//     public String toString() {
//         return key;
//     }
// }


// Path: src/main/java/com/mb3364/twitch/api/auth/grants/implicit/AuthenticationCallbackServer.java
import com.mb3364.twitch.api.auth.Scopes;
import java.io.IOException;
import java.net.*;

        return serverSocket != null;
    }

    @Override
    public void onAccessTokenReceived(String token, Scopes... scopes) {
        accessToken = token;
        accessScopes = scopes;
        stop(); // Stop the server, we no longer need to process requests
    }

    @Override
    public void onAuthenticationError(String error, String description) {
        authenticationError = new AuthenticationError(error, description);
        stop(); // Stop the server
    }

    /**
     * Get the access token if one exists.
     *
     * @return Access token if it exists, <code>null</code> otherwise
     */
    public String getAccessToken() {
        return accessToken;
    }

    /**
     * Get the access scopes for the authenticated user.
     *
     * @return Array of {@link Scopes} that the authenticated user has
     */
    public Scopes[] getAccessScopes() {