// Path: src/com/nixus/raop/core/ServiceContext.java
// public interface ServiceContext {
// 
//     public void debug(String message, Throwable e);
// 
//     public void debug(String message);
// 
//     public void info(String message);
// 
//     public void warn(String message, Throwable e);
// 
//     public void error(String message, Throwable e);
// 
//     /**
//      * Return the name and version of the Software
//      */
//     public String getSoftwareName();
// 
//     /**
//      * Return the logical name of the Server 
//      */
//     public String getServerName();
// 
//     /**
//      * Return the build date of the Server
//      */
//     public Date getServerBuildDate();
// 
//     /**
//      * Return the unique logical name of this Service 
//      */
//     public String getServiceName();
// 
//     /**
//      * Get the Service for this ServiceContext
//      */
//     public Service getService();
// 
//     /**
//      * Get the first {@link Service} object of the specified type
//      */
//     public <E extends Service> E getService(Class<E> type);
// 
//     /**
//      * Get the first {@link Service} object of the specified type
//      */
// 
//     public <E extends Service> E getService(Class<E> type, String criteria);
// 
//     /**
//      * Get a list of all {@link Service} objects of the specified type
//      */
// 
//     public <E extends Service> E[] getServices(Class<E> type, String criteria);
// 
//     /**
//      * Add a {@link Listener} to the Server, it will be notified of events
//      */
//     public void addListener(Listener listener);
// 
//     /**
//      * Remove a {@link Listener} to the Server, it will be notified of events
//      */
//     public void removeListener(Listener listener);
// 
//     /**
//      * Fire an event - the Listeners registered with the server will be notified.
//      * Properties can be specified easily with the second parameter, which is a sequence
//      * of [key, value] entries - eg
//      * <pre>
//      *  qtunes.fireEvent("player.add, new Object[] { "track", track, "user", user });
//      * </pre>
//      * @param o an array of [key, value]
//      */
//     public void fireEvent(String name, Object[] o);
// 
//     /**
//      * Return a list of properties of this Service
//      */
//     public String[] getPropertyNames();
// 
//     /**
//      * Get a system-wide property
//      */
//     public String getGlobalProperty(String key);
// 
//     /**
//      * Get a property of this Service
//      */
//     public String getProperty(String key);
// 
//     /**
//      * Set a property of this Service
//      */
//     public void putProperty(String key, String value);
// 
//     public void start();
// 
//     public void stop();
// 
//     /**
//      * Add a service
//      */
//     public ServiceContext addService(Class<?>[] classes, Service service, Map<String,String> properties, boolean permanent);
// 
//     /**
//      * Remove a service
//      */
//     public void removeService();
// 
//     /**
//      * Return the list of Service names
//      */
//     public String[] getServiceNames();
// 
//     /**
//      * Return true if the Service has been started
//      */
//     public boolean isActive();
// 
// }


import java.io.IOException;
import java.math.BigInteger;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.Provider;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.RSAPublicKeySpec;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeSet;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import com.nixus.raop.core.ServiceContext;
        cipherinput[1] = 0;
    }

    private byte[] doRSAEncrypt(byte[] plaintextbytes) throws GeneralSecurityException {
        BigInteger modulus = new BigInteger("E7D744F2A2E2788B6C1F55A08EB70544A8FA7945AA8BE6C62CE5F51CBDD4DC6842FE3D1083DD2EDEC1BFD4252DC02E6F398BDF0E6148EA84855E2E442DA6D62664F674A1F304929ADE4F6893EF2DF6E711A8C77A0D91C9D980822E50D12922AFEA40EA9F0E14C0F76938C5F3882FC0323DD9FE55155F51BB5921C201629FD73352D5E2EFAABF9BA048D7B813A2B6767F6C3CCF1EB4CE673D037B0D2EA30C5FFFEB06F8D08ADDE409571A9C689FEF10728855DD8CFB9A8BEF5C8943EF3B5FAA15DDE698BEDDF3599603EB3E6F61372BB628F6559F599A78BF500687AA7F4976C0562D412956F8989E18A6355BD81597825E0FC875343EC782117625CDBF98447B", 16);
        BigInteger exponent = new BigInteger("65537");
        KeyFactory keyfactory = KeyFactory.getInstance("RSA");
        PublicKey key = keyfactory.generatePublic(new RSAPublicKeySpec(modulus, exponent));
        // Following cipher name has only been tested with Sun JCE Provider:
        // the naming scheme appears idiosyncratic so may not work with others.
        
        Cipher keycipher = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "Crypto");
        keycipher.init(Cipher.ENCRYPT_MODE, key);
        return keycipher.doFinal(plaintextbytes);
    }

    private synchronized void stop() {
        stpe.shutdownNow();
        stpe = null;
        controlsocket.close();
        timingsocket.close();
        controlsocket = timingsocket = null;
        timingthread.interrupt();
        packetqueue = null;
        context.debug("Stopped AirtunesManager for \""+name+"\"");
    }

    /**
     * Add the named speaker to this set
     */
// Path: src/com/nixus/raop/core/ServiceContext.java
// public interface ServiceContext {
// 
//     public void debug(String message, Throwable e);
// 
//     public void debug(String message);
// 
//     public void info(String message);
// 
//     public void warn(String message, Throwable e);
// 
//     public void error(String message, Throwable e);
// 
//     /**
//      * Return the name and version of the Software
//      */
//     public String getSoftwareName();
// 
//     /**
//      * Return the logical name of the Server 
//      */
//     public String getServerName();
// 
//     /**
//      * Return the build date of the Server
//      */
//     public Date getServerBuildDate();
// 
//     /**
//      * Return the unique logical name of this Service 
//      */
//     public String getServiceName();
// 
//     /**
//      * Get the Service for this ServiceContext
//      */
//     public Service getService();
// 
//     /**
//      * Get the first {@link Service} object of the specified type
//      */
//     public <E extends Service> E getService(Class<E> type);
// 
//     /**
//      * Get the first {@link Service} object of the specified type
//      */
// 
//     public <E extends Service> E getService(Class<E> type, String criteria);
// 
//     /**
//      * Get a list of all {@link Service} objects of the specified type
//      */
// 
//     public <E extends Service> E[] getServices(Class<E> type, String criteria);
// 
//     /**
//      * Add a {@link Listener} to the Server, it will be notified of events
//      */
//     public void addListener(Listener listener);
// 
//     /**
//      * Remove a {@link Listener} to the Server, it will be notified of events
//      */
//     public void removeListener(Listener listener);
// 
//     /**
//      * Fire an event - the Listeners registered with the server will be notified.
//      * Properties can be specified easily with the second parameter, which is a sequence
//      * of [key, value] entries - eg
//      * <pre>
//      *  qtunes.fireEvent("player.add, new Object[] { "track", track, "user", user });
//      * </pre>
//      * @param o an array of [key, value]
//      */
//     public void fireEvent(String name, Object[] o);
// 
//     /**
//      * Return a list of properties of this Service
//      */
//     public String[] getPropertyNames();
// 
//     /**
//      * Get a system-wide property
//      */
//     public String getGlobalProperty(String key);
// 
//     /**
//      * Get a property of this Service
//      */
//     public String getProperty(String key);
// 
//     /**
//      * Set a property of this Service
//      */
//     public void putProperty(String key, String value);
// 
//     public void start();
// 
//     public void stop();
// 
//     /**
//      * Add a service
//      */
//     public ServiceContext addService(Class<?>[] classes, Service service, Map<String,String> properties, boolean permanent);
// 
//     /**
//      * Remove a service
//      */
//     public void removeService();
// 
//     /**
//      * Return the list of Service names
//      */
//     public String[] getServiceNames();
// 
//     /**
//      * Return true if the Service has been started
//      */
//     public boolean isActive();
// 
// }


// Path: src/com/nixus/raop/speaker/airport/AirtunesManager.java
import java.io.IOException;
import java.math.BigInteger;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.Provider;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.RSAPublicKeySpec;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeSet;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import com.nixus.raop.core.ServiceContext;

        cipherinput[1] = 0;
    }

    private byte[] doRSAEncrypt(byte[] plaintextbytes) throws GeneralSecurityException {
        BigInteger modulus = new BigInteger("E7D744F2A2E2788B6C1F55A08EB70544A8FA7945AA8BE6C62CE5F51CBDD4DC6842FE3D1083DD2EDEC1BFD4252DC02E6F398BDF0E6148EA84855E2E442DA6D62664F674A1F304929ADE4F6893EF2DF6E711A8C77A0D91C9D980822E50D12922AFEA40EA9F0E14C0F76938C5F3882FC0323DD9FE55155F51BB5921C201629FD73352D5E2EFAABF9BA048D7B813A2B6767F6C3CCF1EB4CE673D037B0D2EA30C5FFFEB06F8D08ADDE409571A9C689FEF10728855DD8CFB9A8BEF5C8943EF3B5FAA15DDE698BEDDF3599603EB3E6F61372BB628F6559F599A78BF500687AA7F4976C0562D412956F8989E18A6355BD81597825E0FC875343EC782117625CDBF98447B", 16);
        BigInteger exponent = new BigInteger("65537");
        KeyFactory keyfactory = KeyFactory.getInstance("RSA");
        PublicKey key = keyfactory.generatePublic(new RSAPublicKeySpec(modulus, exponent));
        // Following cipher name has only been tested with Sun JCE Provider:
        // the naming scheme appears idiosyncratic so may not work with others.
        
        Cipher keycipher = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "Crypto");
        keycipher.init(Cipher.ENCRYPT_MODE, key);
        return keycipher.doFinal(plaintextbytes);
    }

    private synchronized void stop() {
        stpe.shutdownNow();
        stpe = null;
        controlsocket.close();
        timingsocket.close();
        controlsocket = timingsocket = null;
        timingthread.interrupt();
        packetqueue = null;
        context.debug("Stopped AirtunesManager for \""+name+"\"");
    }

    /**
     * Add the named speaker to this set
     */
    AirtunesSpeaker addSpeaker(String name, InetAddress host, int port, String password, ServiceContext context) {