package com.github.ddth.cql;

import java.net.InetSocketAddress;
import java.util.Collection;
import java.util.HashSet;

import org.apache.commons.lang3.StringUtils;

import com.datastax.driver.core.AuthProvider;
import com.datastax.driver.core.Configuration;
import com.datastax.driver.core.exceptions.AuthenticationException;
import com.datastax.driver.core.exceptions.NoHostAvailableException;
import com.datastax.driver.dse.DseCluster;
import com.datastax.driver.dse.DseSession;
import com.datastax.driver.dse.auth.DsePlainTextAuthProvider;

/**
 * DSE utility class.
 *
 * @author Thanh Nguyen <btnguyen2k@gmail.com>
 * @since 0.4.0.1
 */
public class DseUtils extends CqlUtils {

    /**
     * Build a new DSE cluster instance.
     *
     * @param hostsAndPorts
     *            format: "host1:port1,host2,host3:port3". If no port is
     *            specified, the {@link #DEFAULT_CASSANDRA_PORT} is used.
     * @param username
     * @param password
     * @param proxiedUser
     *            DSE allows a user to connect as another user or role, provide the name of the
     *            user/role you want to connect as via this parameter
     * @return
     */
    public static DseCluster newDseCluster(String hostsAndPorts, String username, String password,
            String proxiedUser) {
        return newDseCluster(hostsAndPorts, username, password, proxiedUser, null);
    }

    /**
     * Build a new DSE cluster instance.
     *
     * @param hostsAndPorts
     *            format: "host1:port1,host2,host3:port3". If no port is
     *            specified, the {@link #DEFAULT_CASSANDRA_PORT} is used.
     * @param username
     * @param password
     * @param proxiedUser
     *            DSE allows a user to connect as another user or role, provide the name of the
     *            user/role you want to connect as via this parameter
     * @param configuration
     * @return
     */
    public static DseCluster newDseCluster(String hostsAndPorts, String username, String password,
            String proxiedUser, Configuration configuration) {
        DseCluster.Builder builder = DseCluster.builder();
        if (!StringUtils.isBlank(username)) {
            AuthProvider authProvider;
            if (StringUtils.isBlank(proxiedUser)) {
                authProvider = new DsePlainTextAuthProvider(username, password);
            } else {
                authProvider = new DsePlainTextAuthProvider(username, password, proxiedUser);
            }
            builder = builder.withAuthProvider(authProvider);
        }
        Collection<InetSocketAddress> contactPointsWithPorts = new HashSet<InetSocketAddress>();
        String[] hostAndPortArr = StringUtils.split(hostsAndPorts, ";, ");
        for (String hostAndPort : hostAndPortArr) {
            String[] tokens = StringUtils.split(hostAndPort, ':');
            String host = tokens[0];
            int port = tokens.length > 1 ? Integer.parseInt(tokens[1]) : DEFAULT_CASSANDRA_PORT;
            contactPointsWithPorts.add(new InetSocketAddress(host, port));
        }
        builder = builder.addContactPointsWithPorts(contactPointsWithPorts);

        buildPolicies(configuration, builder);
        buildOptions(configuration, builder);

        DseCluster cluster = builder.build();
        return cluster;
    }

    /**
     * Create a new session for a DSE cluster, initializes it and sets the keyspace
     * to the provided one.
     *
     * @param cluster
     * @param keyspace
     * @return
     * @throws NoHostAvailableException
     * @throws AuthenticationException
     * @throws IllegalStateException
     */
    public static DseSession newDseSession(DseCluster cluster, String keyspace) {
        return cluster.connect(StringUtils.isBlank(keyspace) ? null : keyspace);
    }
}


package org.intellimate.izou.sdk.frameworks.music.events;

import org.intellimate.izou.identification.Identification;
import org.intellimate.izou.sdk.events.CommonEvents;
import org.intellimate.izou.sdk.events.Event;
import org.intellimate.izou.sdk.frameworks.music.resources.MusicErrorResource;

import java.util.Collections;
import java.util.Optional;

/**
 * @author LeanderK
 * @version 1.0
 */
public class PlayerError extends Event {
    public static final String ID = "izou.music.events.error";
    public static final String ERROR_ALREADY_PLAYING = "1. music-player is already playing";
    public static final String ERROR_NOT_ABLE = "2. music-player is not able to do: ";
    public static final String ERROR_ILLEGAL = "2. music-player is receiving an illegal command: ";

    /**
     * Creates a new Event Object
     *
     * @param source      the source of the Event, most likely a this reference.
     * @throws IllegalArgumentException if one of the Arguments is null or empty
     */
    protected PlayerError(Identification source) throws IllegalArgumentException {
        super(CommonEvents.Type.RESPONSE_TYPE, source, Collections.singletonList(ID));
    }

    /**
     * creates a new MusicPlayerError
     * @param source the source
     * @param error the error (not null and not empty)
     * @return the optional event
     */
    public static Optional<PlayerError> createMusicPlayerError(Identification source, String error) {
        if (error == null || error.isEmpty())
            return Optional.empty();
        try {
            PlayerError playerError = new PlayerError(source);
            playerError.addResource(new MusicErrorResource(source, error));
            return Optional.of(playerError);
        } catch (IllegalArgumentException e) {
            return Optional.empty();
        }
    }
}


package org.intellimate.izou.sdk.frameworks.music.player.template;

import org.intellimate.izou.identification.Identification;
import org.intellimate.izou.identification.IdentificationManager;
import org.intellimate.izou.identification.IdentificationManagerM;
import org.intellimate.izou.sdk.Context;
import org.intellimate.izou.sdk.activator.Activator;
import org.intellimate.izou.sdk.frameworks.music.events.PlayerCommand;
import org.intellimate.izou.sdk.frameworks.music.events.StartMusicRequest;
import org.intellimate.izou.sdk.frameworks.music.events.StopMusic;
import org.intellimate.izou.sdk.frameworks.music.player.Playlist;
import org.intellimate.izou.sdk.frameworks.music.player.Progress;
import org.intellimate.izou.sdk.frameworks.music.player.TrackInfo;
import org.intellimate.izou.sdk.frameworks.music.player.Volume;
import org.intellimate.izou.sdk.frameworks.music.resources.PlaylistResource;
import org.intellimate.izou.sdk.frameworks.music.resources.ProgressResource;
import org.intellimate.izou.sdk.frameworks.music.resources.TrackInfoResource;
import org.intellimate.izou.sdk.frameworks.music.resources.VolumeResource;

import java.util.Optional;

/**
 * you should use this class to control your Player.
 * Use this class even if you don't start/stop in this class. For example if you want to use a 3rd. party library which
 * starts/stops without your interference communicate this with this class. The purpose of this class is not only to
 * stop the Player, but communicate this behaviour to other classes!
 * @author LeanderKfini
 * @version 1.0
 */
public abstract class PlayerController extends Activator {
    private Player player;

    public PlayerController(Context context, String ID, Player player) {
        super(context, ID);
        this.player = player;
    }

    public PlayerController(Context context, String ID) {
        super(context, ID);
        this.player = null;
    }

    public void setPlayer(Player player) {
        this.player = player;
    }

    public Player getPlayer() {
        return player;
    }

    /**
     * starts the playing command
     */
    public void startPlaying() {
        startPlaying((TrackInfo)null);
    }

    /**
     * starts the playing command
     * @param trackInfo the track to play
     */
    public void startPlaying(TrackInfo trackInfo) {
        Optional<Identification> ownIdentification = IdentificationManagerM.getInstance()
                .getIdentification(this);
        Optional<Identification> playerIdentification = IdentificationManagerM.getInstance()
                .getIdentification(player);
        if (!ownIdentification.isPresent() || !playerIdentification.isPresent()) {
            error("unable to obtain identification");
            return;
        }
        StartMusicRequest.createStartMusicRequest(ownIdentification.get(), playerIdentification.get(), trackInfo, player.isUsingJava)
                .ifPresent(event -> fire(event, 5));

    }

    /**
     * starts the playing command
     * @param playlist the playlist to play
     */
    public void startPlaying(Playlist playlist) {
        Optional<Identification> ownIdentification = IdentificationManagerM.getInstance()
                .getIdentification(this);
        Optional<Identification> playerIdentification = IdentificationManagerM.getInstance()
                .getIdentification(player);
        if (!ownIdentification.isPresent() || !playerIdentification.isPresent()) {
            error("unable to obtain identification");
            return;
        }
        StartMusicRequest.createStartMusicRequest(ownIdentification.get(), playerIdentification.get(), playlist, player.isUsingJava)
                .ifPresent(event -> fire(event, 5));

    }

    /**
     * stops the playing of the music
     */
    public void stopPlaying() {
        Optional<Identification> ownIdentification = IdentificationManagerM.getInstance()
                .getIdentification(this);
        Optional<Identification> playerIdentification = IdentificationManagerM.getInstance()
                .getIdentification(player);
        if (!ownIdentification.isPresent()|| !playerIdentification.isPresent()) {
            error("unable to obtain id");
            return;
        }
        StopMusic.createStopMusic(ownIdentification.get(), playerIdentification.get())
                .ifPresent(event -> fire(event, 5));
    }

    /**
     * commands the player to fulfill the command
     * @param command the command
     * @param playlist the playlist, or null if not needed
     * @param progress the progress, or null if not needed
     * @param trackInfo the trackInfo, or null if not needed
     * @param volume the volume, or null if not needed
     */
    public void command(String command, Playlist playlist, Progress progress, TrackInfo trackInfo, Volume volume) {
        Optional<Identification> ownIdentification = IdentificationManagerM.getInstance()
                .getIdentification(this);
        Optional<Identification> playerIdentification = IdentificationManagerM.getInstance()
                .getIdentification(player);
        if (!ownIdentification.isPresent()|| !playerIdentification.isPresent()) {
            error("unable to obtain id");
            return;
        }
        Optional<PlayerCommand> playerCommand = PlayerCommand.createPlayerCommand(ownIdentification.get(),
                playerIdentification.get(), command, player.getCapabilities(), getContext());
        if (playlist != null) {
            playerCommand.get().addResource(new PlaylistResource(ownIdentification.get(), playlist));
        }
        if (progress != null) {
            playerCommand.get().addResource(new ProgressResource(ownIdentification.get(), progress));
        }
        if (trackInfo != null) {
            playerCommand.get().addResource(new TrackInfoResource(ownIdentification.get(), trackInfo));
        }
        if (volume != null) {
            playerCommand.get().addResource(new VolumeResource(ownIdentification.get(), volume));
        }
        fire(playerCommand.get(), 5);
    }
}


package org.intellimate.izou.sdk.frameworks.music.resources;

import org.intellimate.izou.identification.Identification;
import org.intellimate.izou.sdk.frameworks.music.player.Playlist;
import org.intellimate.izou.sdk.resource.Resource;

import java.util.HashMap;

/**
 * use this method obtain a specified Playlist.
 * Internally it keeps the PlaylistData in the HashMap when the request happens, the key is the ResourceID.
 * @author LeanderK
 * @version 1.0
 */
public class BroadcasterPlaylist extends Resource<HashMap<String, Object>> {
    @SuppressWarnings("SpellCheckingInspection")
    public static final String RESOURCE_ID = "izou.music.resource.broadcaster.playlist";

    /**
     * creates a new Resource.
     *
     * @param provider   the Provider of the Resource
     */
    public BroadcasterPlaylist(Identification provider) {
        super(RESOURCE_ID, provider);
    }

    /**
     * creates a new Resource.
     *
     * @param provider   the Provider of the Resource
     * @param hashMap    the resource
     */
    protected BroadcasterPlaylist(Identification provider, HashMap<String, Object> hashMap) {
        super(RESOURCE_ID, provider, hashMap);
    }

    /**
     * creates a new Resource.
     *
     * @param consumer   the ID of the Consumer
     * @param hashMap    the resource
     */
    protected BroadcasterPlaylist(HashMap<String, Object> hashMap, Identification consumer) {
        super(RESOURCE_ID, hashMap, consumer);
    }

    /**
     * creates a new Resource.
     * This method is thread-safe.
     *
     * @param provider   the Provider of the Resource
     * @param consumer   the ID of the Consumer
     */
    protected BroadcasterPlaylist(Identification provider, Identification consumer) {
        super(RESOURCE_ID, provider, consumer);
    }

    /**
     * creates a new Resource.
     *
     * @param provider   the Provider of the Resource
     * @param hashMap    the resource
     * @param consumer   the ID of the Consumer
     */
    protected BroadcasterPlaylist(Identification provider, HashMap<String, Object> hashMap, Identification consumer) {
        super(RESOURCE_ID, provider, hashMap, consumer);
    }

    /**
     * creates the Playlist-Request
     * @param provider the provider of the playlist
     * @param playlistName the name of the playlist
     * @return the resource
     */
    public static BroadcasterPlaylist createPlaylistRequest(Identification provider, String playlistName) {
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put(RESOURCE_ID, playlistName);
        return new BroadcasterPlaylist(provider, hashMap);
    }

    /**
     * creates the Playlist-Answer
     * @param provider the provider
     * @param playlist the playlist
     * @return the resource
     */
    public static BroadcasterPlaylist createPlaylistAnswer(Identification provider, Playlist playlist) {
        return new BroadcasterPlaylist(provider, playlist.export());
    }
}


package org.intellimate.izou.sdk.frameworks.permanentSoundOutput.events;

import org.intellimate.izou.identification.Identification;
import org.intellimate.izou.sdk.events.CommonEvents;
import org.intellimate.izou.sdk.events.Event;
import org.intellimate.izou.sdk.frameworks.common.resources.SelectorResource;
import org.intellimate.izou.system.sound.SoundIDs;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Optional;

/**
 * signals that every sound-output should unmute
 * @author LeanderK
 * @version 1.0
 */
public class UnMuteEvent extends Event {
    public static final String ID = SoundIDs.UnMuteEvent.descriptor;
    /**
     * Creates a new Event Object
     *
     * @param source      the source of the Event, most likely a this reference.
     * @throws IllegalArgumentException if one of the Arguments is null or empty
     */
    protected UnMuteEvent(Identification source)
            throws IllegalArgumentException {
        super(CommonEvents.Type.RESPONSE_TYPE, source, new ArrayList<>(Arrays.asList(ID,
                CommonEvents.Descriptors.STOP_DESCRIPTOR)));
    }

    /**
     * creates a new StopEvent
     * @param source the caller
     * @param target the target who should start playing
     * @return the optional StartMusicRequest
     */
    public static Optional<UnMuteEvent> createUnMuteEvent(Identification source, Identification target) {
        if (target == null || target.equals(source))
            return Optional.empty();
        try {
            UnMuteEvent unmuteRequest = new UnMuteEvent(source);
            unmuteRequest.addResource(new SelectorResource(source, target));
            return Optional.of(unmuteRequest);
        } catch (IllegalArgumentException e) {
            return Optional.empty();
        }
    }
}


/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you 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 uk.co.tfd.sm.template;

import org.apache.velocity.runtime.RuntimeServices;
import org.apache.velocity.runtime.log.LogChute;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A proxy class from velocity to slf4j logging.
 */
public class VelocityLogger implements LogChute {

	private Logger logger;
	protected boolean inDebugMode = false;

	/**
	 * @param class1
	 */
	public VelocityLogger(Class<?> toLogClass) {
		logger = LoggerFactory.getLogger(toLogClass);
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.apache.velocity.runtime.log.LogChute#init(org.apache.velocity.runtime.RuntimeServices)
	 */
	public void init(RuntimeServices arg0) throws Exception {
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.apache.velocity.runtime.log.LogChute#isLevelEnabled(int)
	 */
	public boolean isLevelEnabled(int level) {
		if (inDebugMode) {
			return true;
		}
		switch (level) {
		case LogChute.DEBUG_ID:
			return logger.isDebugEnabled();
		case LogChute.ERROR_ID:
			return logger.isErrorEnabled();
		case LogChute.INFO_ID:
			return logger.isInfoEnabled();
		case LogChute.TRACE_ID:
			return logger.isTraceEnabled();
		case LogChute.WARN_ID:
			return logger.isWarnEnabled();
		}
		return false;
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.apache.velocity.runtime.log.LogChute#log(int, java.lang.String)
	 */
	public void log(int level, String msg) {
		if (inDebugMode) {
			logger.info(msg);
		}
		switch (level) {
		case LogChute.DEBUG_ID:
			logger.debug(msg);
			break;
		case LogChute.ERROR_ID:
			logger.error(msg);
			break;
		case LogChute.INFO_ID:
			logger.info(msg);
			break;
		case LogChute.TRACE_ID:
			logger.trace(msg);
			break;
		case LogChute.WARN_ID:
			logger.warn(msg);
			break;
		}
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.apache.velocity.runtime.log.LogChute#log(int, java.lang.String,
	 *      java.lang.Throwable)
	 */
	public void log(int level, String msg, Throwable t) {
		if (inDebugMode) {
			logger.info(msg, t);
		}
		switch (level) {
		case LogChute.DEBUG_ID:
			logger.debug(msg, t);
			break;
		case LogChute.ERROR_ID:
			logger.error(msg, t);
			break;
		case LogChute.INFO_ID:
			logger.info(msg, t);
			break;
		case LogChute.TRACE_ID:
			logger.trace(msg, t);
			break;
		case LogChute.WARN_ID:
			logger.warn(msg, t);
			break;
		}
	}

	public void setDebugMode(boolean debug) {
		this.inDebugMode = debug;
	}

}


/**
 * Copyright (c) 2012, Jilles van Gurp
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.github.jillesvangurp.urlbuilder;

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.LinkedList;
import java.util.Map.Entry;
import org.apache.commons.lang.StringUtils;

/**
 * Simple builder class to construct urls out of a base url, one or more post fixes, and query parameters.
 *
 * The builder class enables you to not worry about things like trailing slashes, url encoding, etc.
 */
public class UrlBuilder {

    private final StringBuilder url;
    // preserve order in which parameters are added
    private final LinkedList<Entry<String, String>> params = new LinkedList<>();

    private UrlBuilder(String baseUrl) {
        url = new StringBuilder(baseUrl);
    }

    /**
     * @param baseUrl baseUrl
     * @return builder for the baseUrl
     */
    public static UrlBuilder url(String baseUrl) {
        return new UrlBuilder(baseUrl);
    }

    /**
     * @param host host
     * @param port port
     * @return builder for http://[host]:[port]
     */
    public static UrlBuilder url(String host, int port) {
        return new UrlBuilder("http://" + host + ":" + port);
    }

    /**
     * @return URL as a String. Note, you can also use toString.
     */
    public String build() {
    	StringBuilder result=new StringBuilder(url);
        if(params.size() > 0) {
        	result.append('?');

            for (Entry<String, String> entry: params) {
                String value = entry.getValue();
                result.append(entry.getKey() + '=' + value);
                result.append('&');
            }
            result.deleteCharAt(result.length()-1); // remove trailing &
        }
        return result.toString();
    }

    /**
     * @return URL instance
     * @throws IllegalArgumentException in case the URL is not valid (wraps checked MalformedURLException).
     */
    public URL buildUrl() {
        try {
            return new URL(build());
        } catch (MalformedURLException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /**
     * Appends one or more postfixes and separates them by slashes. Note, prefixes are url encoded, so don't include the actual slashes.
     * @param postFix postFix
     * @return the builder.
     */
    public UrlBuilder append(String... postFix) {
        return append(true,postFix);
    }

    /**
     * Appends one or more postfixes and separates them by slashes.
     * @param encode if true, the postFixes are url encoded.
     * @param postFix one or more String values
     * @return the builder
     */
    public UrlBuilder append(boolean encode,String... postFix) {
        for (String part : postFix) {
            if(StringUtils.isNotBlank(part)) {
                if (url.charAt(url.length() - 1) != '/' && !part.startsWith("/")) {
                    url.append('/');
                }
                if(encode) {
                    try {
                        url.append(URLEncoder.encode(part, "UTF-8"));
                    } catch (UnsupportedEncodingException e) {
                        throw new IllegalStateException(e);
                    }
                } else {
                    url.append(part);
                }
            }
        }
        return this;
    }

    /**
     * Create a query parameter with a boolean value.
     * @param name parameter name
     * @param value value
     * @return the builder
     */
    public UrlBuilder queryParam(String name, Boolean value) {
        if(value != null) {
            return queryParam(name, value.toString());
        } else {
            return null;
        }
    }

    /**
     * Create a query parameter with a number value.
     * @param name parameter name
     * @param value value
     * @return the builder
     */
    public UrlBuilder queryParam(String name, Number value) {
        if(value != null) {
            return queryParam(name, value.toString());
        } else {
            return null;
        }
    }

    /**
     * Create a query parameter with a String value. The value will be urlencoded.
     * @param name name
     * @param value value
     * @return the builder
     */
    public UrlBuilder queryParam(String name, String value) {
        return queryParam(name, value, true);
    }

    /**
     * Create a query parameter with a String value.
     * @param name name
     * @param value value
     * @param encode if true, the value is urlencoded.
     * @return the builder
     */
    public UrlBuilder queryParam(String name, String value, boolean encode) {
        if (StringUtils.isNotEmpty(value)) {
            if (encode) {
                try {
                    value = URLEncoder.encode(value, "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    throw new IllegalStateException(e);
                }
            }
            params.add(new EntryImpl(name, value));
        }
        return this;
    }

    @Override
    public String toString() {
        return build();
    }

    private static class EntryImpl implements Entry<String,String> {
        private final String name;
        private final String value;

        public EntryImpl(String name, String value) {
            this.name = name;
            this.value = value;
        }

        @Override
        public String getKey() {
            return name;
        }

        @Override
        public String getValue() {
            return value;
        }

        @Override
        public String setValue(String value) {
            throw new UnsupportedOperationException("entry is immutable");
        }
    }
}


package org.intellimate.izou.sdk.frameworks.music.resources;

import org.intellimate.izou.events.EventModel;
import org.intellimate.izou.identification.Identification;
import org.intellimate.izou.sdk.frameworks.music.player.Playlist;
import org.intellimate.izou.sdk.resource.Resource;

import java.util.HashMap;
import java.util.Optional;

/**
 * this resource is simply used hold the playlist
 * @author LeanderK
 * @version 1.0
 */
public class PlaylistResource extends Resource<HashMap<String, Object>> {
    public static final String ID = "izou.music.resource.playlist";
    /**
     * creates a new Resource.
     * This method is thread-safe.
     *
     * @param provider   the Provider of the Resource
     */
    public PlaylistResource(Identification provider) {
        super(ID, provider);
    }

    /**
     * creates a new Resource.
     * This method is thread-safe.
     *
     * @param provider   the Provider of the Resource
     * @param playlist   the resource
     */
    public PlaylistResource(Identification provider, Playlist playlist) {
        super(ID, provider, playlist.export());
    }

    /**
     * creates a new Resource.
     * This method is thread-safe.
     *
     * @param provider   the Provider of the Resource
     * @param consumer   the ID of the Consumer
     */
    public PlaylistResource(Identification provider, Identification consumer) {
        super(ID, provider, consumer);
    }

    /**
     * creates a new Resource.
     * This method is thread-safe.
     *
     * @param provider   the Provider of the Resource
     * @param playlist   the resource
     * @param consumer   the ID of the Consumer
     */
    public PlaylistResource(Identification provider, Playlist playlist, Identification consumer) {
        super(ID, provider, playlist.export(), consumer);
    }

    /**
     * gets the first playlist if found in the EventModel
     * @param eventModel the EventModel
     * @return return the optional Playlist
     */
    public static Optional<Playlist> getPlaylist(EventModel eventModel) {
        if (eventModel.getListResourceContainer().containsResourcesFromSource(ID)) {
            return eventModel
                    .getListResourceContainer()
                    .provideResource(ID)
                    .stream()
                    .findAny()
                    .flatMap(Playlist::importResource);
        } else {
            return Optional.empty();
        }
    }
}


/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.sakaiproject.nakamura.app;

import java.awt.Color;
import java.awt.Desktop;
import java.awt.Dimension;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JOptionPane;

/**
 * This is a simple Swing GUI to launch Nakamura (primarily for the benefit of Windows
 * users) from a Java Web Start link.
 *

 * I actually developed this in Netbeans, due to it's support of Swing (and Eclipse's lack
 * of) and copied the code into the app package.
 *
 * @author Chris Dunstall (cdunstall@csu.edu.au)
 * @version 1.0 January 6 2011.
 */
public class LaunchNakamura extends javax.swing.JFrame {

  private static final long serialVersionUID = 8161160666368638463L;
  public static final int APP_RUNNING = 1;
  public static final int APP_NOT_RUNNING = 0;
  private static String[] savedArgs;
  private int runStatus = APP_NOT_RUNNING; // 0 for off, 1 for on.
  private static final String localhostURL = "http://localhost:8080/dev/";

  /** Creates new form LaunchNakamura */
  public LaunchNakamura() {
    initComponents();

    ImageIcon icon = createImageIcon("/sakaioae-icon.png", "SakaiOAE Logo");
    headingLabel.setIcon(icon);

    String disclaimer = "";
    try {
      disclaimer = getLabelText("/readme.txt");
    } catch (IOException e) {
      disclaimer = "Use at own risk.";
    }

    disclaimerLabel.setText(disclaimer);
    disclaimerLabel.setPreferredSize(new Dimension(1, 1));

    browserButton.setEnabled(false);
  }

  /**
   * This method is called from within the constructor to initialize the form.
   *

   * Note: This code was generated by Netbeans.
   */
  private void initComponents() {

    launchButton = new javax.swing.JButton();
    statusLabel = new javax.swing.JLabel();
    exitButton = new javax.swing.JButton();
    headingLabel = new javax.swing.JLabel();
    disclaimerLabel = new javax.swing.JLabel();
    browserButton = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setTitle("Launch Nakamura");
    setName("mainFrame"); // NOI18N
    setResizable(false);

    launchButton.setFont(new java.awt.Font("Arial", 0, 13)); // NOI18N
    launchButton.setText("Launch");
    launchButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        launchButtonActionPerformed(evt);
      }
    });

    statusLabel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N
    statusLabel.setText("Nakamura is not running.");

    exitButton.setFont(new java.awt.Font("Arial", 0, 13)); // NOI18N
    exitButton.setText("Exit");
    exitButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        exitButtonActionPerformed(evt);
      }
    });

    headingLabel.setText("SakaiOAE icon");
    headingLabel.setBorder(javax.swing.BorderFactory.createEtchedBorder());

    disclaimerLabel.setFont(new java.awt.Font("Arial", 0, 13)); // NOI18N
    disclaimerLabel.setText("jLabel1");
    disclaimerLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP);
    disclaimerLabel.setAutoscrolls(true);
    disclaimerLabel.setBorder(javax.swing.BorderFactory.createTitledBorder("Disclaimer"));

    browserButton.setText("Open Sakai OAE");
    browserButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        browserButtonActionPerformed(evt);
      }
    });

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(layout.createParallelGroup(
        javax.swing.GroupLayout.Alignment.LEADING).addGroup(
        layout
            .createSequentialGroup()
            .addGroup(
                layout
                    .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(
                        layout
                            .createSequentialGroup()
                            .addGap(27, 27, 27)
                            .addComponent(launchButton)
                            .addGap(18, 18, 18)
                            .addComponent(statusLabel)
                            .addPreferredGap(
                                javax.swing.LayoutStyle.ComponentPlacement.RELATED, 162,
                                Short.MAX_VALUE)
                            .addComponent(browserButton)
                            .addPreferredGap(
                                javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(exitButton))
                    .addGroup(
                        javax.swing.GroupLayout.Alignment.CENTER,
                        layout
                            .createSequentialGroup()
                            .addContainerGap()
                            .addComponent(headingLabel,
                                javax.swing.GroupLayout.PREFERRED_SIZE, 149,
                                javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGap(18, 18, 18)
                            .addComponent(disclaimerLabel,
                                javax.swing.GroupLayout.PREFERRED_SIZE, 493,
                                javax.swing.GroupLayout.PREFERRED_SIZE)))
            .addContainerGap()));

    layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {
        exitButton, launchButton });

    layout.setVerticalGroup(layout
        .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(
            javax.swing.GroupLayout.Alignment.TRAILING,
            layout
                .createSequentialGroup()
                .addContainerGap()
                .addGroup(
                    layout
                        .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(disclaimerLabel,
                            javax.swing.GroupLayout.PREFERRED_SIZE, 215,
                            javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(headingLabel,
                            javax.swing.GroupLayout.PREFERRED_SIZE, 116,
                            javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(58, 58, 58)
                .addGroup(
                    layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                        .addComponent(browserButton).addComponent(exitButton))
                .addContainerGap())
        .addGroup(
            layout
                .createSequentialGroup()
                .addGap(259, 259, 259)
                .addGroup(
                    layout
                        .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(launchButton,
                            javax.swing.GroupLayout.PREFERRED_SIZE, 50,
                            javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(statusLabel))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));

    pack();
  }

  /**
   * This is the launch button action method. This method launches the Apache Sling
   * bootloader and informs the user to wait before accessing it in a browser.
   *
   * @param evt
   *          The details of the Action event.
   * @throws IOException
   */
  private void launchButtonActionPerformed(java.awt.event.ActionEvent evt) {
    // Launch Nakamura
    if (runStatus == APP_NOT_RUNNING) {
      System.setSecurityManager(null);
      try {
        NakamuraMain.main(savedArgs);

        // Update label
        statusLabel.setText("Nakamura is starting...");

        // Notify the user
        JOptionPane.showMessageDialog(this,
            "Nakamura has been started.\nPlease allow 30-60 seconds for it to be ready.",
            "Information", JOptionPane.INFORMATION_MESSAGE);

        runStatus = APP_RUNNING;
        isStartupFinished();
      } catch (IOException e) {
        statusLabel.setText("Nakamura is startup failed " + e.getMessage());
      }
    } else {
      // Can't start it again...
      // custom title, warning icon
      JOptionPane.showMessageDialog(this, "Nakamura is already running.", "Warning",
          JOptionPane.WARNING_MESSAGE);
    }
  }

  /**
   * Pings the Apache Sling server URL every 5 seconds to see if it has finished booting.
   * Once it receives an OK status, it enables the button to launch the browser and
   * disables the launch Nakamura button.
   */
  private void isStartupFinished() {
    boolean started = false;
    try {
      while (!started) {
        if (exists(localhostURL))
          started = true;
        Thread.sleep(5 * 1000);
      }
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    if (started) {
      statusLabel.setText("Nakamura is running.");
      statusLabel.setForeground(Color.green);
      launchButton.setEnabled(false);
      browserButton.setEnabled(true);
    }
  }

  /**
   * Pings the Apache Sling server URL, looking for an OK status. Returns true once that
   * OK status is received.
   *
   * @param URLName
   *          The URL to ping.
   * @return true if OK status is received back. False if not OK.
   */
  public static boolean exists(String URLName) {
    try {
      HttpURLConnection.setFollowRedirects(false);
      // note : you may also need
      // HttpURLConnection.setInstanceFollowRedirects(false)
      HttpURLConnection con = (HttpURLConnection) new URL(URLName).openConnection();
      con.setRequestMethod("HEAD");
      return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }

  /**
   * Performs the action when the exit button is pressed, which is exit the program.
   *
   * @param evt
   *          The details of the event.
   */
  private void exitButtonActionPerformed(java.awt.event.ActionEvent evt) {
    // Kill Nakamura and the GUI app.
    System.exit(0);
  }

  /**
   * Performs the action when the browser button is pressed, which is launch a web browser
   * and browse to the server URL.
   *
   * @param evt
   *          The details of the event.
   */
  private void browserButtonActionPerformed(java.awt.event.ActionEvent evt) {
    try {
      Desktop.getDesktop().browse(new URL(localhostURL).toURI());
    } catch (IOException e) {
      System.err.println("IO Exception: " + e.getMessage());
    } catch (URISyntaxException e) {
      System.err.println("URISyntaxException: " + e.getMessage());
    }
  }

  /**
   * Returns an ImageIcon, or null if the path was invalid.
   *
   * @param path
   *          The path to the icon.
   * @param description
   *          The description of the icon.
   * @return the newly created ImageIcon or null.
   */
  protected ImageIcon createImageIcon(String path, String description) {
    java.net.URL imgURL = getClass().getResource(path);
    if (imgURL != null) {
      return new ImageIcon(imgURL, description);
    } else {
      System.err.println("Couldn't find file: " + path);
      return null;
    }
  }

  /**
   * Returns the full contents of a (assumed) text file for use in a label.
   *
   * @param path
   *          The path to the text file.
   * @return The contents of the file as a String.
   * @throws IOException
   *           thrown if the file is unable to be read.
   */
  protected String getLabelText(String path) throws IOException {
    InputStream is = this.getClass().getResourceAsStream(path);
    if (is != null) {
      Writer writer = new StringWriter();

      char[] buffer = new char[1024];
      try {
        Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        int n;
        while ((n = reader.read(buffer)) != -1) {
          writer.write(buffer, 0, n);
        }
      } finally {
        is.close();
      }
      return writer.toString();
    } else {
      System.err.println("Couldn't find file: " + path);
      return null;
    }
  }

  /**
   * The Main method which executes the program.
   *
   * @param args
   *          the command line arguments
   */
  public static void main(String args[]) {
    savedArgs = args;
    java.awt.EventQueue.invokeLater(new Runnable() {

      public void run() {
        new LaunchNakamura().setVisible(true);
      }
    });
  }

  // Variables declaration - do not modify
  private javax.swing.JButton browserButton;
  private javax.swing.JLabel disclaimerLabel;
  private javax.swing.JButton exitButton;
  private javax.swing.JLabel headingLabel;
  private javax.swing.JButton launchButton;
  private javax.swing.JLabel statusLabel;
  // End of variables declaration

}


/*
 * Copyright 2010 Workplace Systems PLC (http://www.workplacesystems.com/).
 *
 * 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.workplacesystems.utilsj.collections;

import java.util.Arrays;
/** Decorator for an int[] with some array-level arithmetic */
public class IntArray
{
    public int[] value;
    public int length;

    /** Create contents with 'length' items, all zero */
    public IntArray(int length)
    {
        value = new int[length];
        this.length = length;
    }

    /** Replace contents with given values */
    public IntArray with(int... values)
    {
        if (values.length != this.length)
            throw new IllegalArgumentException("Array size mismatch");
        value = values.clone();
        return this;
    }

    public void add(int... others)
    {
        if (others.length != this.length)
            throw new IllegalArgumentException("Array size mismatch");
        for (int i=0; i<length; i++)
            value[i] += others[i];
    }

    public void inc(boolean... others)
    {
        if (others.length != this.length)
            throw new IllegalArgumentException("Array size mismatch");
        for (int i=0; i<length; i++)
            if (others[i]) value[i]++;
    }

    public void add(IntArray other)
    {
        add(other.value);
    }

    @Override
    public boolean equals(Object obj)
    {
        return obj instanceof IntArray
            && Arrays.equals(value, ((IntArray)obj).value);
    }

    public Integer[] toIntegers()
    {
        Integer[] result = new Integer[length];
        for (int i=0; i<length; i++)
            result[i] = value[i];
        return result;
    }
}


package org.intellimate.izou.sdk.frameworks.presence.provider;

import org.intellimate.izou.resource.ResourceModel;

import java.util.HashMap;
import java.util.Optional;

/**
 * this class holds all important information about the Presence of the user
 * @author LeanderK
 * @version 1.0
 */
public class Presence {
    public static final String LEVEL_DESCRIPTOR = "izou.presence.provider.presence.level";
    private final PresenceIndicatorLevel level;
    public static final String PRESENT_DESCRIPTOR = "izou.presence.provider.presence.present";
    private final boolean present;
    public static final String STRICT_DESCRIPTOR = "izou.presence.provider.presence.strict";
    private final boolean strict;
    public static final String KNOWN_DESCRIPTOR = "izou.presence.provider.presence.known";
    private final boolean known;

    /**
     * returns a new Presence-Object
     * @param level the level of the Presence (mostly used internally)
     * @param present whether it is present
     * @param strict whether it is strict
     * @param known whether it is known that the user caused this
     */
    public Presence(PresenceIndicatorLevel level, boolean present, boolean strict, boolean known) {
        this.level = level;
        this.present = present;
        this.strict = strict;
        this.known = known;
    }

    /**
     * returns the (vague) level of the reliability of the data. Mostly used internally)
     * @return the Level
     */
    public PresenceIndicatorLevel getLevel() {
        return level;
    }

    /**
     * whether it is present AND known
     * @return true if present
     */
    public boolean isPresent() {
        if (known) return present;
        else return false;
    }

    /**
     * whether it is strict (very high probability that the user is around)
     * @return true if strict
     */
    public boolean isStrict() {
        return strict;
    }

    /**
     * whether it is known that the user cause the Event
     * @return true if known
     */
    public boolean isKnown() {
        return known;
    }

    /**
     * exports the Presence to a HashMap
     * @return the resulting HashMap
     */
    public HashMap<String, Object> export() {
        HashMap<String, Object> data = new HashMap<>();
        data.put(LEVEL_DESCRIPTOR, level.name());
        data.put(PRESENT_DESCRIPTOR, present);
        data.put(STRICT_DESCRIPTOR, strict);
        data.put(KNOWN_DESCRIPTOR, known);
        return data;
    }

    /**
     * imports (if no errors occurred) the Presence from the ResourceModel
     * @param resourceModel the resourcemodel to import from
     * @return the (optional) presence
     */
    public static Optional<Presence> importPresence(ResourceModel resourceModel) {
        Object resource = resourceModel.getResource();
        try {
            //noinspection unchecked
            HashMap<String, Object> data = (HashMap<String, Object>) resource;
            PresenceIndicatorLevel level;
            try {
                level = PresenceIndicatorLevel.valueOf((String) data.get(LEVEL_DESCRIPTOR));
            } catch (IllegalArgumentException e) {
                level = PresenceIndicatorLevel.VERY_WEAK;
            }
            boolean present = (boolean) data.get(PRESENT_DESCRIPTOR);
            boolean strict = (boolean) data.get(STRICT_DESCRIPTOR);
            boolean known = (boolean) data.get(KNOWN_DESCRIPTOR);
            return Optional.of(new Presence(level, present, strict, known));
        } catch (Exception e) {
            return Optional.empty();
        }
    }
}


package org.firepick;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.json.simple.parser.*;
import org.json.simple.*;

/**
 * Fluent wrapper for JSON result returned by FireREST
 */
public class JSONResult {
  static Logger logger = LoggerFactory.getLogger(JSONResult.class);
  Object value;

  protected JSONResult(Object value) {
    this.value = value;
  }

  /**
   * Parse given JSON string and set current JSON value
   *
   * @param JSON string
   * @throw FireRESTException if json is invalid
   */
  public JSONResult(String json) {
    if (json == null) {
      value = null;
    } else {
      try {
	JSONParser parser = new JSONParser();
	value = (JSONObject) parser.parse(json);
      } catch (Exception e) {
	throw new FireRESTException("Could not parse: " + json, e);
      }
    }
  }

  /**
   * Advance current JSON value to specified element in JSON array.
   * Set current JSON value to null otherwise.
   *
   * @param index zero-based JSON array index
   * @return JSONResult for fluent method chaining
   */
  public JSONResult get(int index) {
    if (value instanceof JSONArray) {
      JSONArray array = (JSONArray) value;
      Object result = array.get(index);
      return new JSONResult(result);
    } else if (value instanceof JSONObject) {
      return get(String.valueOf(index));
    }
    return new JSONResult(null);
  }

  /**
   * Advance current JSON value to specified value of current JSON object.
   * Set current JSON value to null otherwise.
   *
   * @param key element key
   * @return JSONResult for fluent method chaining
   */
  public JSONResult get(String key) {
    if (value instanceof JSONObject) {
      JSONObject obj = (JSONObject) value;
      Object result = obj.get(key);
      return new JSONResult(result);
    } else if (value instanceof JSONArray) {
      try {
	int index = Integer.parseInt(key);
	return get(index);
      } catch(NumberFormatException e) {
        throw createException("Excpected JSONObject " + key + ":");
      }
    }
    return new JSONResult(null);
  }

  private FireRESTException createException(String msg) {
    if (value instanceof JSONArray) {
      return new FireRESTException(msg + ((JSONArray) value).toJSONString());
    }
    if (value instanceof JSONObject) {
      return new FireRESTException(msg + ((JSONObject) value).toJSONString());
    }
    if (value == null) {
      return new FireRESTException(msg + "null");
    }
    throw new FireRESTException(msg + value.toString());
  }

  /**
   * Return false if current element exists
   */
  public boolean isNull() {
    return value == null;
  }

  /**
   * Return an integer for current JSON value, parsing string values as required.
   */
  public Integer getInt() {
    return getInt(null);
  }

  /**
   * Return an integer for current JSON value, parsing string values as required.
   */
  public Integer getInt(Integer defaultValue) {
    if (value instanceof Number) {
      return ((Number) value).intValue();
    }
    if (value instanceof String) {
      String s = (String) value;
      return Integer.parseInt(s);
    }
    if (value == null) {
      return defaultValue;
    }
    throw createException("Expected integer:");
  }

  /**
   * Return a double number for current JSON value, parsing string values as required.
   */
  public Double getDouble() {
    return getDouble(null);
  }

  /**
   * Return a double number for current JSON value, parsing string values as required.
   */
  public Double getDouble(Double defaultValue) {
    if (value instanceof Number) {
      return ((Number) value).doubleValue();
    }
    if (value instanceof String) {
      String s = (String) value;
      return Double.parseDouble(s);
    }
    if (value == null) {
      return defaultValue;
    }
    throw createException("Expected number:");
  }

  /**
   * Return string value for current JSON value
   */
  public String getString() {
    return getString(null);
  }

  /**
   * Return string value for current JSON value
   */
  public String getString(String defaultValue) {
    if (value instanceof String || value instanceof Number) {
      return value.toString();
    }
    if (value == null) {
      return null;
    }
    if (value instanceof JSONArray) {
      return ((JSONArray) value).toJSONString();
    }
    if (value instanceof JSONObject) {
      return ((JSONObject) value).toJSONString();
    }
    if (value == null) {
      return defaultValue;
    }
    throw createException("Expected string:");
  }

  @Override
  public boolean equals(Object thatObj) {
    if (thatObj instanceof JSONResult) {
      JSONResult that = (JSONResult) thatObj;
      if (this.value == that.value) {
        return true;
      }
      if (this.value == null || that.value == null) {
        return false;
      }
      return getString().equals(that.getString());
    }
    return toString().equals(thatObj);
  }

  @Override
  public String toString() {
    return value == null ? "null" : getString();
  }

}


package org.intellimate.izou.sdk.frameworks.music.resources;

import org.intellimate.izou.identification.Identification;
import org.intellimate.izou.sdk.Context;
import org.intellimate.izou.sdk.frameworks.music.Capabilities;
import org.intellimate.izou.sdk.resource.Resource;

import java.util.Optional;

/**
 * A resource containing commands for the player.
 * @author LeanderK
 * @version 1.0
 */
public class CommandResource extends Resource<String> {
    public final static String ResourceID = "izou.music.resource.command";
    public final static String PLAY = "play";
    public final static String PAUSE = "pause";
    public final static String STOP = "stop";
    public final static String SELECT_TRACK = "select";
    public final static String NEXT = "next";
    public static final String PREVIOUS = "previous";
    public static final String JUMP = "jump";
    @SuppressWarnings("SpellCheckingInspection")
    public static final String CHANGE_PLAYBACK = "changeplayback";
    @SuppressWarnings("SpellCheckingInspection")
    public static final String CHANGE_VOLUME = "changevolume";

    /**
     * creates a new Resource.
     *
     * @param provider   the Provider of the Resource
     * @param command          the resource
     * @param capabilities the capabilities of the player
     */
    private CommandResource(Identification provider, String command, Capabilities capabilities) {
        super(ResourceID, provider, command);
        if (!verifyCommand(command))
            throw new IllegalArgumentException("IllegalCommand!");
        if (!verifyCapabilities(command, capabilities))
            throw new IllegalArgumentException("Player is not able to handle Command");
    }

    /**
     * creates a new Resource.
     *
     * @param provider   the Provider of the Resource
     * @param command          the resource
     * @param capabilities the capabilities of the player
     * @param context used for logging
     * @return the commandResource if nothing illegal was passed
     */
    public static Optional<CommandResource> createCommandResource(Identification provider, String command, Capabilities capabilities, Context context) {
        CommandResource commandResource = new CommandResource(provider, command, capabilities);
        if (!verifyCommand(command)) {
            context.getLogger().error("IllegalCommand!");
            return Optional.empty();
        }
        if (!verifyCapabilities(command, capabilities)) {
            context.getLogger().error("Player is not able to handle Command!");
            return Optional.empty();
        }
        return Optional.of(commandResource);
    }

    /**
     * verifies that an command is not malformed
     * @param command the Command
     * @return false if malformed
     */
    public static boolean verifyCommand(String command) {
        return command.equals(PLAY) ||
                command.equals(PAUSE) ||
                command.equals(STOP) ||
                command.equals(SELECT_TRACK) ||
                command.equals(NEXT) ||
                command.equals(PREVIOUS) ||
                command.equals(CHANGE_PLAYBACK) ||
                command.equals(CHANGE_VOLUME);
    }

    /**
     * verifies that the player is capable of handling the command
     * @param command the command
     * @param capabilities the capabilities
     * @return true if capable, false if not
     */
    public static boolean verifyCapabilities(String command, Capabilities capabilities) {
        switch (command) {
            case PLAY: return capabilities.hasPlayPauseControl();
            case PAUSE: return capabilities.hasPlayPauseControl();
            case SELECT_TRACK: return capabilities.isAbleToSelectTrack();
            case NEXT: return capabilities.hasNextPrevious();
            case PREVIOUS: return capabilities.hasNextPrevious();
            case JUMP: return capabilities.isAbleToJump();
            case CHANGE_PLAYBACK: return capabilities.isPlaybackChangeable();
            case CHANGE_VOLUME: return capabilities.canChangeVolume();
            case STOP: return true;
        }
        return false;
    }

    /**
     * verifies tha the command is legal and able to be executed
     * @param command the command
     * @param capabilities the capabilities
     * @return true if able, false if not
     */
    public static boolean verify(String command, Capabilities capabilities) {
        return verifyCommand(command) && verifyCapabilities(command, capabilities);
    }
}