Index: org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaSession.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaSession.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaSession.java	(working copy)
@@ -1,92 +0,0 @@
-/**
- * $RCSfile: TestMediaSession.java,v $
- * $Revision: 1.1 $
- * $Date: 08/11/2006
- * <p/>
- * Copyright 2003-2006 Jive Software.
- * <p/>
- * All rights reserved. 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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.jivesoftware.smackx.jingle.mediaimpl.test;
-
-import org.jivesoftware.smackx.jingle.JingleSession;
-import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
-import org.jivesoftware.smackx.jingle.media.PayloadType;
-import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
-
-/**
- * This Class implements a complete JingleMediaSession for unit testing.
- *
- * @author Thiago Camargo
- */
-public class TestMediaSession extends JingleMediaSession {
-
-     /**
-     * Creates a TestMediaSession with defined payload type, remote and local candidates
-     *
-     * @param payloadType Payload of the jmf
-     * @param remote      the remote information. The candidate that the jmf will be sent to.
-     * @param local       the local information. The candidate that will receive the jmf
-     * @param locator     media locator
-     */
-    public TestMediaSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local,
-            final String locator, JingleSession jingleSession) {
-        super(payloadType, remote, local, "Test", jingleSession);
-        initialize();
-    }
-
-    /**
-     * Initialize the screen share channels.
-     */
-    public void initialize() {
-
-    }
-
-    /**
-     * Starts transmission and for NAT Traversal reasons start receiving also.
-     */
-    public void startTrasmit() {
-        
-    }
-
-    /**
-     * Set transmit activity. If the active is true, the instance should trasmit.
-     * If it is set to false, the instance should pause transmit.
-     *
-     * @param active active state
-     */
-    public void setTrasmit(boolean active) {
-        
-    }
-
-    /**
-     * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
-     */
-    public void startReceive() {
-        // Do nothing
-    }
-
-    /**
-     * Stops transmission and for NAT Traversal reasons stop receiving also.
-     */
-    public void stopTrasmit() {
-       
-    }
-
-    /**
-     * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
-     */
-    public void stopReceive() {
-       
-    }
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaManager.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaManager.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaManager.java	(working copy)
@@ -1,93 +0,0 @@
-/**
- * $RCSfile: TestMediaManager.java,v $
- * $Revision: 1.3 $
- * $Date: 25/12/2006
- * <p/>
- * Copyright 2003-2006 Jive Software.
- * <p/>
- * All rights reserved. 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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.jivesoftware.smackx.jingle.mediaimpl.test;
-
-import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
-import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
-import org.jivesoftware.smackx.jingle.media.PayloadType;
-import org.jivesoftware.smackx.jingle.nat.JingleTransportManager;
-import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
-import org.jivesoftware.smackx.jingle.JingleSession;
-
-import java.util.*;
-
-/**
- * Implements a MediaManager for test purposes.
- *
- * @author Thiago Camargo
- */
-
-public class TestMediaManager extends JingleMediaManager {
-
-    public static final String MEDIA_NAME = "TestMedia";
-
-    private List<PayloadType> payloads = new ArrayList<PayloadType>();
-
-    private PayloadType preferredPayloadType = null;
-
-    public TestMediaManager(JingleTransportManager transportManager) {
-        super(transportManager);
-    }
-
-    /**
-    * Return all supported Payloads for this Manager.
-    *
-    * @return The Payload List
-    */
-    public List<PayloadType> getPayloads() {
-        return payloads;
-    }
-
-    public void setPayloads(List<PayloadType> payloads) {
-        this.payloads.addAll(payloads);
-    }
-
-    /**
-     * Returns a new JingleMediaSession
-     *
-     * @param payloadType payloadType
-     * @param remote      remote Candidate
-     * @param local       local Candidate
-     * @return JingleMediaSession JingleMediaSession
-     */
-    public JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote,
-            final TransportCandidate local, final JingleSession jingleSession) {
-        TestMediaSession session = null;
-
-        session = new TestMediaSession(payloadType, remote, local, "", jingleSession);
-
-        return session;
-    }
-
-    public PayloadType getPreferredPayloadType() {
-        if (preferredPayloadType != null)
-            return preferredPayloadType;
-        return super.getPreferredPayloadType();
-    }
-
-    public void setPreferredPayloadType(PayloadType preferredPayloadType) {
-        this.preferredPayloadType = preferredPayloadType;
-    }
-
-    public String getName() {
-        return MEDIA_NAME;
-    }
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/JMFInit.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/JMFInit.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/JMFInit.java	(working copy)
@@ -1,282 +0,0 @@
-package org.jivesoftware.smackx.jingle.mediaimpl;
-
-import java.awt.Frame;
-import java.awt.TextArea;
-import java.awt.Toolkit;
-import java.util.Vector;
-
-import javax.media.Format;
-import javax.media.PlugInManager;
-import javax.media.Renderer;
-import javax.media.format.AudioFormat;
-
-import org.jivesoftware.smackx.jingle.SmackLogger;
-
-import com.sun.media.ExclusiveUse;
-import com.sun.media.util.Registry;
-
-public class JMFInit extends Frame implements Runnable {
-
-	private static final SmackLogger LOGGER = SmackLogger.getLogger(JMFInit.class);
-
-	private String tempDir = "/tmp";
-
-    private boolean done = false;
-
-    private String userHome;
-
-    private boolean visible = false;
-
-    public JMFInit(String[] args, boolean visible) {
-        super("Initializing JMF...");
-
-        this.visible = visible;
-
-        Registry.set("secure.allowCaptureFromApplets", true);
-        Registry.set("secure.allowSaveFileFromApplets", true);
-
-        updateTemp(args);
-
-        try {
-            Registry.commit();
-        }
-        catch (Exception e) {
-
-            message("Failed to commit to JMFRegistry!");
-        }
-
-        Thread detectThread = new Thread(this);
-        detectThread.run();
-
-        /*
-           * int slept = 0; while (!done && slept < 60 * 1000 * 2) { try {
-           * Thread.currentThread().sleep(500); } catch (InterruptedException ie) { }
-           * slept += 500; }
-           *
-           * if (!done) { console.error("Detection is taking too long!
-           * Aborting!"); message("Detection is taking too long! Aborting!"); }
-           *
-           * try { Thread.currentThread().sleep(2000); } catch
-           * (InterruptedException ie) { }
-           */
-    }
-
-    public void run() {
-        detectDirectAudio();
-        detectS8DirectAudio();
-        detectCaptureDevices();
-        done = true;
-    }
-
-    private void updateTemp(String[] args) {
-        if (args != null && args.length > 0) {
-            tempDir = args[0];
-
-            message("Setting cache directory to " + tempDir);
-            Registry r = new Registry();
-            try {
-                r.set("secure.cacheDir", tempDir);
-                r.commit();
-
-                message("Updated registry");
-            }
-            catch (Exception e) {
-                message("Couldn't update registry!");
-            }
-        }
-    }
-
-    private void detectCaptureDevices() {
-        // check if JavaSound capture is available
-        message("Looking for Audio capturer");
-        Class dsauto;
-        try {
-            dsauto = Class.forName("DirectSoundAuto");
-            dsauto.newInstance();
-            message("Finished detecting DirectSound capturer");
-        }
-        catch (ThreadDeath td) {
-            throw td;
-        }
-        catch (Throwable t) {
-            //Do nothing
-        }
-
-        Class jsauto;
-        try {
-            jsauto = Class.forName("JavaSoundAuto");
-            jsauto.newInstance();
-            message("Finished detecting javasound capturer");
-        }
-        catch (ThreadDeath td) {
-            throw td;
-        }
-        catch (Throwable t) {
-            message("JavaSound capturer detection failed!");
-        }
-
-        /*
-        // Check if VFWAuto or SunVideoAuto is available
-        message("Looking for video capture devices");
-        Class auto = null;
-        Class autoPlus = null;
-        try {
-            auto = Class.forName("VFWAuto");
-        }
-        catch (Exception e) {
-        }
-        if (auto == null) {
-            try {
-                auto = Class.forName("SunVideoAuto");
-            }
-            catch (Exception ee) {
-
-            }
-            try {
-                autoPlus = Class.forName("SunVideoPlusAuto");
-            }
-            catch (Exception ee) {
-
-            }
-        }
-        if (auto == null) {
-            try {
-                auto = Class.forName("V4LAuto");
-            }
-            catch (Exception ee) {
-
-            }
-        }
-        try {
-            Object instance = auto.newInstance();
-            if (autoPlus != null) {
-                Object instancePlus = autoPlus.newInstance();
-            }
-
-            message("Finished detecting video capture devices");
-        }
-        catch (ThreadDeath td) {
-            throw td;
-        }
-        catch (Throwable t) {
-
-            message("Capture device detection failed!");
-        }
-        */
-    }
-
-    private void detectDirectAudio() {
-        Class cls;
-        int plType = PlugInManager.RENDERER;
-        String dar = "com.sun.media.renderer.audio.DirectAudioRenderer";
-        try {
-            // Check if this is the Windows Performance Pack - hack
-            cls = Class.forName("VFWAuto");
-            // Check if DS capture is supported, otherwise fail DS renderer
-            // since NT doesn't have capture
-            cls = Class.forName("com.sun.media.protocol.dsound.DSound");
-            // Find the renderer class and instantiate it.
-            cls = Class.forName(dar);
-
-            Renderer rend = (Renderer) cls.newInstance();
-            try {
-                // Set the format and open the device
-                AudioFormat af = new AudioFormat(AudioFormat.LINEAR, 44100, 16,
-                        2);
-                rend.setInputFormat(af);
-                rend.open();
-                Format[] inputFormats = rend.getSupportedInputFormats();
-                // Register the device
-                PlugInManager.addPlugIn(dar, inputFormats, new Format[0],
-                        plType);
-                // Move it to the top of the list
-                Vector rendList = PlugInManager.getPlugInList(null, null,
-                        plType);
-                int listSize = rendList.size();
-                if (rendList.elementAt(listSize - 1).equals(dar)) {
-                    rendList.removeElementAt(listSize - 1);
-                    rendList.insertElementAt(dar, 0);
-                    PlugInManager.setPlugInList(rendList, plType);
-                    PlugInManager.commit();
-                    // Log.debug("registered");
-                }
-                rend.close();
-            }
-            catch (Throwable t) {
-                // Log.debug("Error " + t);
-            }
-        }
-        catch (Throwable tt) {
-            //Do nothing
-        }
-    }
-
-    private void detectS8DirectAudio() {
-        Class cls;
-        int plType = PlugInManager.RENDERER;
-        String dar = "com.sun.media.renderer.audio.DirectAudioRenderer";
-        try {
-            // Check if this is the solaris Performance Pack - hack
-            cls = Class.forName("SunVideoAuto");
-
-            // Find the renderer class and instantiate it.
-            cls = Class.forName(dar);
-
-            Renderer rend = (Renderer) cls.newInstance();
-
-            if (rend instanceof ExclusiveUse
-                    && !((ExclusiveUse) rend).isExclusive()) {
-                // sol8+, DAR supports mixing
-                Vector rendList = PlugInManager.getPlugInList(null, null,
-                        plType);
-                int listSize = rendList.size();
-                boolean found = false;
-                String rname = null;
-
-                for (int i = 0; i < listSize; i++) {
-                    rname = (String) (rendList.elementAt(i));
-                    if (rname.equals(dar)) { // DAR is in the registry
-                        found = true;
-                        rendList.removeElementAt(i);
-                        break;
-                    }
-                }
-
-                if (found) {
-                    rendList.insertElementAt(dar, 0);
-                    PlugInManager.setPlugInList(rendList, plType);
-                    PlugInManager.commit();
-                }
-            }
-        }
-        catch (Throwable tt) {
-            //Do nothing
-        }
-    }
-
-    private void message(String mesg) {
-        LOGGER.debug(mesg);
-    }
-
-    private void createGUI() {
-        TextArea textBox = new TextArea(5, 50);
-        add("Center", textBox);
-        textBox.setEditable(false);
-        addNotify();
-        pack();
-
-        int scrWidth = (int) Toolkit.getDefaultToolkit().getScreenSize()
-                .getWidth();
-        int scrHeight = (int) Toolkit.getDefaultToolkit().getScreenSize()
-                .getHeight();
-
-        setLocation((scrWidth - getWidth()) / 2, (scrHeight - getHeight()) / 2);
-
-        setVisible(visible);
-
-    }
-
-    public static void start(boolean visible) {
-        new JMFInit(null, visible);
-    }
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/demo/Demo.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/demo/Demo.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/demo/Demo.java	(working copy)
@@ -1,174 +0,0 @@
-/**
- * $RCSfile: Demo.java,v $
- * $Revision: 1.3 $
- * $Date: 28/12/2006
- * <p/>
- * Copyright 2003-2006 Jive Software.
- * <p/>
- * All rights reserved. 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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.jivesoftware.smackx.jingle.mediaimpl.demo;
-
-import org.jivesoftware.smack.Connection;
-import org.jivesoftware.smack.XMPPConnection;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smackx.jingle.JingleManager;
-import org.jivesoftware.smackx.jingle.JingleSession;
-import org.jivesoftware.smackx.jingle.JingleSessionRequest;
-import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener;
-import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
-import org.jivesoftware.smackx.jingle.mediaimpl.jspeex.SpeexMediaManager;
-import org.jivesoftware.smackx.jingle.mediaimpl.sshare.ScreenShareMediaManager;
-import org.jivesoftware.smackx.jingle.nat.ICETransportManager;
-import org.jivesoftware.smackx.jingle.nat.JingleTransportManager;
-
-import javax.swing.*;
-import java.awt.event.ActionEvent;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Jingle Demo Application. It register in a XMPP Server and let users place calls using a full JID and auto-receive calls.
- * Parameters: Server User Pass.
- */
-public class Demo extends JFrame {
-
-    private JingleTransportManager transportManager = null;
-    private Connection xmppConnection = null;
-
-    private String server = null;
-    private String user = null;
-    private String pass = null;
-
-    private JingleManager jm = null;
-    private JingleSession incoming = null;
-    private JingleSession outgoing = null;
-
-    private JTextField jid;
-
-    public Demo(String server, String user, String pass) {
-
-        this.server = server;
-        this.user = user;
-        this.pass = pass;
-        
-        if (user.equals("jeffw")) {
-            jid = new JTextField("eowyn" + "@" + server + "/Smack");
-        } else {
-            jid = new JTextField("jeffw" + "@" + server + "/Smack");
-        }
-
-        xmppConnection = new XMPPConnection(server);
-        try {
-            xmppConnection.connect();
-            xmppConnection.login(user, pass);
-            initialize();
-        }
-        catch (XMPPException e) {
-            e.printStackTrace();
-        }
-    }
-
-    public void initialize() {
-        ICETransportManager icetm0 = new ICETransportManager(xmppConnection, "10.47.47.53", 3478);
-        List<JingleMediaManager> mediaManagers = new ArrayList<JingleMediaManager>();
-        //mediaManagers.add(new JmfMediaManager(icetm0));
-        mediaManagers.add(new SpeexMediaManager(icetm0));
-        mediaManagers.add(new ScreenShareMediaManager(icetm0));
-        jm = new JingleManager(xmppConnection, mediaManagers);
-        jm.addCreationListener(icetm0);
-
-        jm.addJingleSessionRequestListener(new JingleSessionRequestListener() {
-            public void sessionRequested(JingleSessionRequest request) {
-
-//                if (incoming != null)
-//                    return;
-
-                try {
-                    // Accept the call
-                    incoming = request.accept();
-
-                    // Start the call
-                    incoming.startIncoming();
-                }
-                catch (XMPPException e) {
-                    e.printStackTrace();
-                }
-
-            }
-        });
-        createGUI();
-    }
-
-    public void createGUI() {
-
-        JPanel jPanel = new JPanel();
-
-        jPanel.add(jid);
-
-        jPanel.add(new JButton(new AbstractAction("Call") {
-            public void actionPerformed(ActionEvent e) {
-                if (outgoing != null) return;
-                try {
-                    outgoing = jm.createOutgoingJingleSession(jid.getText());
-                    outgoing.startOutgoing();
-                }
-                catch (XMPPException e1) {
-                    e1.printStackTrace();
-                }
-            }
-        }));
-
-        jPanel.add(new JButton(new AbstractAction("Hangup") {
-            public void actionPerformed(ActionEvent e) {
-                if (outgoing != null)
-                    try {
-                        outgoing.terminate();
-                    }
-                    catch (XMPPException e1) {
-                        e1.printStackTrace();
-                    }
-                    finally {
-                        outgoing = null;
-                    }
-                if (incoming != null)
-                    try {
-                        incoming.terminate();
-                    }
-                    catch (XMPPException e1) {
-                        e1.printStackTrace();
-                    }
-                    finally {
-                        incoming = null;
-                    }
-            }
-        }));
-
-        this.add(jPanel);
-
-    }
-
-    public static void main(String args[]) {
-
-        Demo demo = null;
-
-        if (args.length > 2) {
-            demo = new Demo(args[0], args[1], args[2]);
-            demo.pack();
-            demo.setVisible(true);
-            demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-        }
-
-    }
-
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareSession.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareSession.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareSession.java	(working copy)
@@ -1,206 +0,0 @@
-/**
- * $RCSfile: ScreenShareSession.java,v $
- * $Revision: 1.2 $
- * $Date: 08/11/2006
- * <p/>
- * Copyright 2003-2006 Jive Software.
- * <p/>
- * All rights reserved. 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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.jivesoftware.smackx.jingle.mediaimpl.sshare;
-
-import java.awt.Rectangle;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import java.io.IOException;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.UnknownHostException;
-
-import javax.swing.JFrame;
-import javax.swing.JPanel;
-
-import org.jivesoftware.smackx.jingle.JingleSession;
-import org.jivesoftware.smackx.jingle.SmackLogger;
-import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
-import org.jivesoftware.smackx.jingle.media.PayloadType;
-import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageDecoder;
-import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageEncoder;
-import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageReceiver;
-import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageTransmitter;
-import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
-
-/**
- * This Class implements a complete JingleMediaSession.
- * It sould be used to transmit and receive captured images from the Display.
- * This Class should be automaticly controlled by JingleSession.
- * For better NAT Traversal support this implementation don't support only receive or only transmit.
- * To receive you MUST transmit. So the only implemented and functionally methods are startTransmit() and stopTransmit()
- *
- * @author Thiago Camargo
- */
-public class ScreenShareSession extends JingleMediaSession {
-
-	private static final SmackLogger LOGGER = SmackLogger.getLogger(ScreenShareSession.class);
-
-	private ImageTransmitter transmitter = null;
-    private ImageReceiver receiver = null;
-    private int width = 600;
-    private int height = 600;
-
-    /**
-     * Creates a org.jivesoftware.jingleaudio.jmf.AudioMediaSession with defined payload type, remote and local candidates
-     *
-     * @param payloadType Payload of the jmf
-     * @param remote      the remote information. The candidate that the jmf will be sent to.
-     * @param local       the local information. The candidate that will receive the jmf
-     * @param locator     media locator
-     */
-    public ScreenShareSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local,
-            final String locator, JingleSession jingleSession) {
-        super(payloadType, remote, local, "Screen", jingleSession);
-        initialize();
-    }
-
-    /**
-     * Initialize the screen share channels.
-     */
-    public void initialize() {
-
-        JingleSession session = getJingleSession();
-        if ((session != null) && (session.getInitiator().equals(session.getConnection().getUser()))) {
-            // If the initiator of the jingle session is us then we transmit a screen share.
-            try {
-                InetAddress remote = InetAddress.getByName(getRemote().getIp());
-                transmitter = new ImageTransmitter(new DatagramSocket(getLocal().getPort()), remote, getRemote().getPort(),
-                        new Rectangle(0, 0, width, height));
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-
-        } else {
-            // Otherwise we receive a screen share.
-            JFrame window = new JFrame();
-            JPanel jp = new JPanel();
-            window.add(jp);
-
-            window.setLocation(0, 0);
-            window.setSize(600, 600);
-
-            window.addWindowListener(new WindowAdapter() {
-                public void windowClosed(WindowEvent e) {
-                    receiver.stop();
-                }
-            });
-
-            try {
-                receiver = new ImageReceiver(InetAddress.getByName("0.0.0.0"), getRemote().getPort(), getLocal().getPort(), width,
-                        height);
-                LOGGER.debug("Receiving on:" + receiver.getLocalPort());
-            } catch (UnknownHostException e) {
-                e.printStackTrace();
-            }
-
-            jp.add(receiver);
-            receiver.setVisible(true);
-            window.setAlwaysOnTop(true);
-            window.setVisible(true);
-        }
-    }
-
-    /**
-     * Starts transmission and for NAT Traversal reasons start receiving also.
-     */
-    public void startTrasmit() {
-        new Thread(transmitter).start();
-    }
-
-    /**
-     * Set transmit activity. If the active is true, the instance should trasmit.
-     * If it is set to false, the instance should pause transmit.
-     *
-     * @param active active state
-     */
-    public void setTrasmit(boolean active) {
-        transmitter.setTransmit(true);
-    }
-
-    /**
-     * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
-     */
-    public void startReceive() {
-        // Do nothing
-    }
-
-    /**
-     * Stops transmission and for NAT Traversal reasons stop receiving also.
-     */
-    public void stopTrasmit() {
-        if (transmitter != null) {
-            transmitter.stop();
-        }
-    }
-
-    /**
-     * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
-     */
-    public void stopReceive() {
-        if (receiver != null) {
-            receiver.stop();
-        }
-    }
-
-    /**
-     * Obtain a free port we can use.
-     *
-     * @return A free port number.
-     */
-    protected int getFreePort() {
-        ServerSocket ss;
-        int freePort = 0;
-
-        for (int i = 0; i < 10; i++) {
-            freePort = (int) (10000 + Math.round(Math.random() * 10000));
-            freePort = freePort % 2 == 0 ? freePort : freePort + 1;
-            try {
-                ss = new ServerSocket(freePort);
-                freePort = ss.getLocalPort();
-                ss.close();
-                return freePort;
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
-        try {
-            ss = new ServerSocket(0);
-            freePort = ss.getLocalPort();
-            ss.close();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return freePort;
-    }
-
-    public void setEncoder(ImageEncoder encoder) {
-        if (encoder != null) {
-            this.transmitter.setEncoder(encoder);
-        }
-    }
-
-    public void setDecoder(ImageDecoder decoder) {
-        if (decoder != null) {
-            this.receiver.setDecoder(decoder);
-        }
-    }
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageTransmitter.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageTransmitter.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageTransmitter.java	(working copy)
@@ -1,204 +0,0 @@
-package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
-
-import java.awt.AWTException;
-import java.awt.Rectangle;
-import java.awt.Robot;
-import java.awt.image.BufferedImage;
-import java.awt.image.PixelGrabber;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-import java.util.Arrays;
-
-import org.jivesoftware.smackx.jingle.SmackLogger;
-
-/**
- * UDP Image Receiver.
- * It uses PNG Tiles into UDP packets.
- *
- * @author Thiago Rocha Camargo
- */
-public class ImageTransmitter implements Runnable {
-
-	private static final SmackLogger LOGGER = SmackLogger.getLogger(ImageTransmitter.class);
-
-	private Robot robot;
-    private InetAddress localHost;
-    private InetAddress remoteHost;
-    private int localPort;
-    private int remotePort;
-    public static final int tileWidth = 25;
-    private boolean on = true;
-    private boolean transmit = false;
-    private DatagramSocket socket;
-    private Rectangle area;
-    private int tiles[][][];
-    private int maxI;
-    private int maxJ;
-    private ImageEncoder encoder;
-    public final static int KEYFRAME = 10;
-
-    public ImageTransmitter(DatagramSocket socket, InetAddress remoteHost, int remotePort, Rectangle area) {
-
-        try {
-            robot = new Robot();
-
-            maxI = (int) Math.ceil(area.getWidth() / tileWidth);
-            maxJ = (int) Math.ceil(area.getHeight() / tileWidth);
-
-            tiles = new int[maxI][maxJ][tileWidth * tileWidth];
-
-            this.area = area;
-            this.socket = socket;
-            localHost = socket.getLocalAddress();
-            localPort = socket.getLocalPort();
-            this.remoteHost = remoteHost;
-            this.remotePort = remotePort;
-            this.encoder = new DefaultEncoder();
-
-            transmit = true;
-
-        }
-        catch (AWTException e) {
-            e.printStackTrace();
-        }
-
-    }
-
-    public void start() {
-        byte buf[] = new byte[1024];
-        final DatagramPacket p = new DatagramPacket(buf, 1024);
-
-        int keyframe = 0;
-
-        while (on) {
-            if (transmit) {
-
-                BufferedImage capture = robot.createScreenCapture(area);
-
-                QuantizeFilter filter = new QuantizeFilter();
-                capture = filter.filter(capture, null);
-
-                long trace = System.currentTimeMillis();
-
-                if (++keyframe > KEYFRAME) {
-                    keyframe = 0;
-                }
-                LOGGER.debug("KEYFRAME:" + keyframe);
-
-                for (int i = 0; i < maxI; i++) {
-                    for (int j = 0; j < maxJ; j++) {
-
-                        final BufferedImage bufferedImage = capture.getSubimage(i * tileWidth, j * tileWidth, tileWidth, tileWidth);
-
-                        int pixels[] = new int[tileWidth * tileWidth];
-
-                        PixelGrabber pg = new PixelGrabber(bufferedImage, 0, 0, tileWidth, tileWidth, pixels, 0, tileWidth);
-
-                        try {
-                            if (pg.grabPixels()) {
-
-                                if (keyframe == KEYFRAME || !Arrays.equals(tiles[i][j], pixels)) {
-
-                                    ByteArrayOutputStream baos = encoder.encode(bufferedImage);
-
-                                    if (baos != null) {
-
-                                        try {
-
-                                            Thread.sleep(1);
-
-                                            baos.write(i);
-                                            baos.write(j);
-
-                                            byte[] bytesOut = baos.toByteArray();
-
-                                            if (bytesOut.length > 1000)
-                                                LOGGER.error("Bytes out > 1000. Equals " + bytesOut.length);
-
-                                            p.setData(bytesOut);
-                                            p.setAddress(remoteHost);
-                                            p.setPort(remotePort);
-
-                                            try {
-                                                socket.send(p);
-                                            }
-                                            catch (IOException e) {
-                                                e.printStackTrace();
-                                            }
-
-                                            tiles[i][j] = pixels;
-
-                                        }
-                                        catch (Exception e) {
-                                        }
-
-                                    }
-
-                                }
-
-                            }
-                        }
-                        catch (InterruptedException e) {
-                            e.printStackTrace();
-                        }
-                    }
-                }
-
-                trace = (System.currentTimeMillis() - trace);
-                LOGGER.debug("Loop Time:" + trace);
-
-                if (trace < 500) {
-                    try {
-                        Thread.sleep(500 - trace);
-                    }
-                    catch (InterruptedException e) {
-                        e.printStackTrace();
-                    }
-                }
-            }
-        }
-    }
-
-    public void run() {
-        start();
-    }
-
-    /**
-     * Set Transmit Enabled/Disabled
-     *
-     * @param transmit boolean Enabled/Disabled
-     */
-    public void setTransmit(boolean transmit) {
-        this.transmit = transmit;
-    }
-
-    /**
-     * Get the encoder used to encode Images Tiles
-     *
-     * @return encoder
-     */
-    public ImageEncoder getEncoder() {
-        return encoder;
-    }
-
-    /**
-     * Set the encoder used to encode Image Tiles
-     *
-     * @param encoder encoder
-     */
-    public void setEncoder(ImageEncoder encoder) {
-        this.encoder = encoder;
-    }
-
-    /**
-     * Stops Transmitter
-     */
-    public void stop() {
-        this.transmit = false;
-        this.on = false;
-        socket.close();
-    }
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageEncoder.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageEncoder.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageEncoder.java	(working copy)
@@ -1,13 +0,0 @@
-package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
-
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayOutputStream;
-
-/**
- * Image Encoder Interface use this interface if you want to change the default encoder
-  *
- * @author Thiago Rocha Camargo
- */
-public interface ImageEncoder {
-    public ByteArrayOutputStream encode(BufferedImage bufferedImage);
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/PixelUtils.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/PixelUtils.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/PixelUtils.java	(working copy)
@@ -1,223 +0,0 @@
-/*
-Copyright 2006 Jerry Huxtable
-
-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 org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
-
-import java.awt.*;
-import java.util.Random;
-
-/**
- * Some more useful math functions for image processing.
- * These are becoming obsolete as we move to Java2D. Use MiscComposite instead.
- */
-public class PixelUtils {
-
-	public final static int REPLACE = 0;
-	public final static int NORMAL = 1;
-	public final static int MIN = 2;
-	public final static int MAX = 3;
-	public final static int ADD = 4;
-	public final static int SUBTRACT = 5;
-	public final static int DIFFERENCE = 6;
-	public final static int MULTIPLY = 7;
-	public final static int HUE = 8;
-	public final static int SATURATION = 9;
-	public final static int VALUE = 10;
-	public final static int COLOR = 11;
-	public final static int SCREEN = 12;
-	public final static int AVERAGE = 13;
-	public final static int OVERLAY = 14;
-	public final static int CLEAR = 15;
-	public final static int EXCHANGE = 16;
-	public final static int DISSOLVE = 17;
-	public final static int DST_IN = 18;
-	public final static int ALPHA = 19;
-	public final static int ALPHA_TO_GRAY = 20;
-
-	private static Random randomGenerator = new Random();
-
-	/**
-	 * Clamp a value to the range 0..255
-	 */
-	public static int clamp(int c) {
-		if (c < 0)
-			return 0;
-		if (c > 255)
-			return 255;
-		return c;
-	}
-
-	public static int interpolate(int v1, int v2, float f) {
-		return clamp((int)(v1+f*(v2-v1)));
-	}
-	
-	public static int brightness(int rgb) {
-		int r = (rgb >> 16) & 0xff;
-		int g = (rgb >> 8) & 0xff;
-		int b = rgb & 0xff;
-		return (r+g+b)/3;
-	}
-	
-	public static boolean nearColors(int rgb1, int rgb2, int tolerance) {
-		int r1 = (rgb1 >> 16) & 0xff;
-		int g1 = (rgb1 >> 8) & 0xff;
-		int b1 = rgb1 & 0xff;
-		int r2 = (rgb2 >> 16) & 0xff;
-		int g2 = (rgb2 >> 8) & 0xff;
-		int b2 = rgb2 & 0xff;
-		return Math.abs(r1-r2) <= tolerance && Math.abs(g1-g2) <= tolerance && Math.abs(b1-b2) <= tolerance;
-	}
-	
-	private final static float hsb1[] = new float[3];//FIXME-not thread safe
-	private final static float hsb2[] = new float[3];//FIXME-not thread safe
-	
-	// Return rgb1 painted onto rgb2
-	public static int combinePixels(int rgb1, int rgb2, int op) {
-		return combinePixels(rgb1, rgb2, op, 0xff);
-	}
-	
-	public static int combinePixels(int rgb1, int rgb2, int op, int extraAlpha, int channelMask) {
-		return (rgb2 & ~channelMask) | combinePixels(rgb1 & channelMask, rgb2, op, extraAlpha);
-	}
-	
-	public static int combinePixels(int rgb1, int rgb2, int op, int extraAlpha) {
-		if (op == REPLACE)
-			return rgb1;
-		int a1 = (rgb1 >> 24) & 0xff;
-		int r1 = (rgb1 >> 16) & 0xff;
-		int g1 = (rgb1 >> 8) & 0xff;
-		int b1 = rgb1 & 0xff;
-		int a2 = (rgb2 >> 24) & 0xff;
-		int r2 = (rgb2 >> 16) & 0xff;
-		int g2 = (rgb2 >> 8) & 0xff;
-		int b2 = rgb2 & 0xff;
-
-		switch (op) {
-		case NORMAL:
-			break;
-		case MIN:
-			r1 = Math.min(r1, r2);
-			g1 = Math.min(g1, g2);
-			b1 = Math.min(b1, b2);
-			break;
-		case MAX:
-			r1 = Math.max(r1, r2);
-			g1 = Math.max(g1, g2);
-			b1 = Math.max(b1, b2);
-			break;
-		case ADD:
-			r1 = clamp(r1+r2);
-			g1 = clamp(g1+g2);
-			b1 = clamp(b1+b2);
-			break;
-		case SUBTRACT:
-			r1 = clamp(r2-r1);
-			g1 = clamp(g2-g1);
-			b1 = clamp(b2-b1);
-			break;
-		case DIFFERENCE:
-			r1 = clamp(Math.abs(r1-r2));
-			g1 = clamp(Math.abs(g1-g2));
-			b1 = clamp(Math.abs(b1-b2));
-			break;
-		case MULTIPLY:
-			r1 = clamp(r1*r2/255);
-			g1 = clamp(g1*g2/255);
-			b1 = clamp(b1*b2/255);
-			break;
-		case DISSOLVE:
-			if ((randomGenerator.nextInt() & 0xff) <= a1) {
-				r1 = r2;
-				g1 = g2;
-				b1 = b2;
-			}
-			break;
-		case AVERAGE:
-			r1 = (r1+r2)/2;
-			g1 = (g1+g2)/2;
-			b1 = (b1+b2)/2;
-			break;
-		case HUE:
-		case SATURATION:
-		case VALUE:
-		case COLOR:
-			Color.RGBtoHSB(r1, g1, b1, hsb1);
-			Color.RGBtoHSB(r2, g2, b2, hsb2);
-			switch (op) {
-			case HUE:
-				hsb2[0] = hsb1[0];
-				break;
-			case SATURATION:
-				hsb2[1] = hsb1[1];
-				break;
-			case VALUE:
-				hsb2[2] = hsb1[2];
-				break;
-			case COLOR:
-				hsb2[0] = hsb1[0];
-				hsb2[1] = hsb1[1];
-				break;
-			}
-			rgb1 = Color.HSBtoRGB(hsb2[0], hsb2[1], hsb2[2]);
-			r1 = (rgb1 >> 16) & 0xff;
-			g1 = (rgb1 >> 8) & 0xff;
-			b1 = rgb1 & 0xff;
-			break;
-		case SCREEN:
-			r1 = 255 - ((255 - r1) * (255 - r2)) / 255;
-			g1 = 255 - ((255 - g1) * (255 - g2)) / 255;
-			b1 = 255 - ((255 - b1) * (255 - b2)) / 255;
-			break;
-		case OVERLAY:
-			int m, s;
-			s = 255 - ((255 - r1) * (255 - r2)) / 255;
-			m = r1 * r2 / 255;
-			r1 = (s * r1 + m * (255 - r1)) / 255;
-			s = 255 - ((255 - g1) * (255 - g2)) / 255;
-			m = g1 * g2 / 255;
-			g1 = (s * g1 + m * (255 - g1)) / 255;
-			s = 255 - ((255 - b1) * (255 - b2)) / 255;
-			m = b1 * b2 / 255;
-			b1 = (s * b1 + m * (255 - b1)) / 255;
-			break;
-		case CLEAR:
-			r1 = g1 = b1 = 0xff;
-			break;
-		case DST_IN:
-			r1 = clamp((r2*a1)/255);
-			g1 = clamp((g2*a1)/255);
-			b1 = clamp((b2*a1)/255);
-			a1 = clamp((a2*a1)/255);
-			return (a1 << 24) | (r1 << 16) | (g1 << 8) | b1;
-		case ALPHA:
-			a1 = a1*a2/255;
-			return (a1 << 24) | (r2 << 16) | (g2 << 8) | b2;
-		case ALPHA_TO_GRAY:
-			int na = 255-a1;
-			return (a1 << 24) | (na << 16) | (na << 8) | na;
-		}
-		if (extraAlpha != 0xff || a1 != 0xff) {
-			a1 = a1*extraAlpha/255;
-			int a3 = (255-a1)*a2/255;
-			r1 = clamp((r1*a1+r2*a3)/255);
-			g1 = clamp((g1*a1+g2*a3)/255);
-			b1 = clamp((b1*a1+b2*a3)/255);
-			a1 = clamp(a1+a3);
-		}
-		return (a1 << 24) | (r1 << 16) | (g1 << 8) | b1;
-	}
-
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/Quantizer.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/Quantizer.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/Quantizer.java	(working copy)
@@ -1,53 +0,0 @@
-/*
-Copyright 2006 Jerry Huxtable
-
-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 org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
-
-/**
- * The interface for an image quantizer. The addColor method is called (repeatedly
- * if necessary) with all the image pixels. A color table can then be returned by 
- * calling the buildColorTable method.
- */
-public interface Quantizer {
-	/**
-	 * Initialize the quantizer. This should be called before adding any pixels.
-	 * @param numColors the number of colors we're quantizing to.
-	 */
-	public void setup(int numColors);
-	
-	/**
-	 * Add pixels to the quantizer.
-	 * @param pixels the array of ARGB pixels
-	 * @param offset the offset into the array
-	 * @param count the count of pixels
-	 */
-	public void addPixels(int[] pixels, int offset, int count);
-	
-	/**
-	 * Build a color table from the added pixels.
-	 * @return an array of ARGB pixels representing a color table
-	 */
-	public int[] buildColorTable();
-	
-	/**
-	 * Using the previously-built color table, return the index into that table for a pixel.
-	 * This is guaranteed to return a valid index - returning the index of a color closer
-	 * to that requested if necessary. 
-	 * @param rgb the pixel to find
-	 * @return the pixel's index in the color table
-	 */
-	public int getIndexForColor(int rgb);
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultEncoder.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultEncoder.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultEncoder.java	(working copy)
@@ -1,24 +0,0 @@
-package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
-
-import javax.imageio.ImageIO;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-/**
- * Implements a default PNG Encoder
- */
-public class DefaultEncoder implements ImageEncoder{
-
-    public ByteArrayOutputStream encode(BufferedImage bufferedImage) {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try {
-            ImageIO.write(bufferedImage, "png", baos);
-        }
-        catch (IOException e) {
-            e.printStackTrace();
-            baos = null;
-        }
-        return baos;
-    }
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/QuantizeFilter.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/QuantizeFilter.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/QuantizeFilter.java	(working copy)
@@ -1,178 +0,0 @@
-/*
-Copyright 2006 Jerry Huxtable
-
-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 org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
-
-import java.awt.*;
-
-/**
- * A filter which quantizes an image to a set number of colors - useful for producing
- * images which are to be encoded using an index color model. The filter can perform
- * Floyd-Steinberg error-diffusion dithering if required. At present, the quantization
- * is done using an octtree algorithm but I eventually hope to add more quantization
- * methods such as median cut. Note: at present, the filter produces an image which
- * uses the RGB color model (because the application it was written for required it).
- * I hope to extend it to produce an IndexColorModel by request.
- */
-public class QuantizeFilter extends WholeImageFilter {
-
-	/**
-	 * Floyd-Steinberg dithering matrix.
-	 */
-	protected final static int[] matrix = {
-	 	 0, 0, 0,
-	 	 0, 0, 7,
-	 	 3, 5, 1,
-	};
-	private int sum = 3+5+7+1;
-
-	private boolean dither;
-	private int numColors = 256;
-	private boolean serpentine = true;
-
-	/**
-	 * Set the number of colors to quantize to.
-	 * @param numColors the number of colors. The default is 256.
-	 */
-	public void setNumColors(int numColors) {
-		this.numColors = Math.min(Math.max(numColors, 8), 256);
-	}
-
-	/**
-	 * Get the number of colors to quantize to.
-	 * @return the number of colors.
-	 */
-	public int getNumColors() {
-		return numColors;
-	}
-
-	/**
-	 * Set whether to use dithering or not. If not, the image is posterized.
-	 * @param dither true to use dithering
-	 */
-	public void setDither(boolean dither) {
-		this.dither = dither;
-	}
-
-	/**
-	 * Return the dithering setting
-	 * @return the current setting
-	 */
-	public boolean getDither() {
-		return dither;
-	}
-
-	/**
-	 * Set whether to use a serpentine pattern for return or not. This can reduce 'avalanche' artifacts in the output.
-	 * @param serpentine true to use serpentine pattern
-	 */
-	public void setSerpentine(boolean serpentine) {
-		this.serpentine = serpentine;
-	}
-	
-	/**
-	 * Return the serpentine setting
-	 * @return the current setting
-	 */
-	public boolean getSerpentine() {
-		return serpentine;
-	}
-	
-	public void quantize(int[] inPixels, int[] outPixels, int width, int height, int numColors, boolean dither, boolean serpentine) {
-		int count = width*height;
-		Quantizer quantizer = new OctTreeQuantizer();
-		quantizer.setup(numColors);
-		quantizer.addPixels(inPixels, 0, count);
-		int[] table =  quantizer.buildColorTable();
-
-		if (!dither) {
-			for (int i = 0; i < count; i++)
-				outPixels[i] = table[quantizer.getIndexForColor(inPixels[i])];
-		} else {
-			int index = 0;
-			for (int y = 0; y < height; y++) {
-				boolean reverse = serpentine && (y & 1) == 1;
-				int direction;
-				if (reverse) {
-					index = y*width+width-1;
-					direction = -1;
-				} else {
-					index = y*width;
-					direction = 1;
-				}
-				for (int x = 0; x < width; x++) {
-					int rgb1 = inPixels[index];
-					int rgb2 = table[quantizer.getIndexForColor(rgb1)];
-
-					outPixels[index] = rgb2;
-
-					int r1 = (rgb1 >> 16) & 0xff;
-					int g1 = (rgb1 >> 8) & 0xff;
-					int b1 = rgb1 & 0xff;
-
-					int r2 = (rgb2 >> 16) & 0xff;
-					int g2 = (rgb2 >> 8) & 0xff;
-					int b2 = rgb2 & 0xff;
-
-					int er = r1-r2;
-					int eg = g1-g2;
-					int eb = b1-b2;
-
-					for (int i = -1; i <= 1; i++) {
-						int iy = i+y;
-						if (0 <= iy && iy < height) {
-							for (int j = -1; j <= 1; j++) {
-								int jx = j+x;
-								if (0 <= jx && jx < width) {
-									int w;
-									if (reverse)
-										w = matrix[(i+1)*3-j+1];
-									else
-										w = matrix[(i+1)*3+j+1];
-									if (w != 0) {
-										int k = reverse ? index - j : index + j;
-										rgb1 = inPixels[k];
-										r1 = (rgb1 >> 16) & 0xff;
-										g1 = (rgb1 >> 8) & 0xff;
-										b1 = rgb1 & 0xff;
-										r1 += er * w/sum;
-										g1 += eg * w/sum;
-										b1 += eb * w/sum;
-										inPixels[k] = (PixelUtils.clamp(r1) << 16) | (PixelUtils.clamp(g1) << 8) | PixelUtils.clamp(b1);
-									}
-								}
-							}
-						}
-					}
-					index += direction;
-				}
-			}
-		}
-	}
-
-	protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
-		int[] outPixels = new int[width*height];
-		
-		quantize(inPixels, outPixels, width, height, numColors, dither, serpentine);
-
-		return outPixels;
-	}
-
-	public String toString() {
-		return "Colors/Quantize...";
-	}
-	
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageReceiver.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageReceiver.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageReceiver.java	(working copy)
@@ -1,150 +0,0 @@
-package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
-
-import java.awt.*;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-import java.net.SocketException;
-
-/**
- * UDP Image Receiver.
- * It uses PNG Tiles into UDP packets.
- *
- * @author Thiago Rocha Camargo
- */
-public class ImageReceiver extends Canvas {
-
-    private boolean on = true;
-    private DatagramSocket socket;
-    private BufferedImage tiles[][];
-    private static final int tileWidth = ImageTransmitter.tileWidth;
-    private InetAddress localHost;
-    private InetAddress remoteHost;
-    private int localPort;
-    private int remotePort;
-    private ImageDecoder decoder;
-
-    public ImageReceiver(final InetAddress remoteHost, final int remotePort, final int localPort, int width, int height) {
-        tiles = new BufferedImage[width][height];
-
-        try {
-
-            socket = new DatagramSocket(localPort);
-            localHost = socket.getLocalAddress();
-            this.remoteHost = remoteHost;
-            this.remotePort = remotePort;
-            this.localPort = localPort;
-            this.decoder = new DefaultDecoder();
-
-            new Thread(new Runnable() {
-                public void run() {
-                    byte buf[] = new byte[1024];
-                    DatagramPacket p = new DatagramPacket(buf, 1024);
-                    try {
-                        while (on) {
-                            socket.receive(p);
-
-                            int length = p.getLength();
-
-                            BufferedImage bufferedImage = decoder.decode(new ByteArrayInputStream(p.getData(), 0, length - 2));
-
-                            if (bufferedImage != null) {
-
-                                int x = p.getData()[length - 2];
-                                int y = p.getData()[length - 1];
-
-                                drawTile(x, y, bufferedImage);
-
-                            }
-
-                        }
-                    }
-                    catch (IOException e) {
-                        e.printStackTrace();
-                    }
-                }
-            }).start();
-
-            new Thread(new Runnable() {
-                public void run() {
-                    byte buf[] = new byte[1024];
-                    DatagramPacket p = new DatagramPacket(buf, 1024);
-                    try {
-                        while (on) {
-
-                            p.setAddress(remoteHost);
-                            p.setPort(remotePort);
-                            socket.send(p);
-
-                            try {
-                                Thread.sleep(1000);
-                            }
-                            catch (InterruptedException e) {
-                                e.printStackTrace();
-                            }
-
-                        }
-                    }
-                    catch (IOException e) {
-                        e.printStackTrace();
-                    }
-                }
-            }).start();
-
-        }
-        catch (SocketException e) {
-            e.printStackTrace();
-        }
-        this.setSize(width, height);
-    }
-
-    public InetAddress getLocalHost() {
-        return localHost;
-    }
-
-    public InetAddress getRemoteHost() {
-        return remoteHost;
-    }
-
-    public int getLocalPort() {
-        return localPort;
-    }
-
-    public int getRemotePort() {
-        return remotePort;
-    }
-
-    public DatagramSocket getDatagramSocket() {
-        return socket;
-    }
-
-    public void drawTile(int x, int y, BufferedImage bufferedImage) {
-        tiles[x][y] = bufferedImage;
-        //repaint(x * tileWidth, y * tileWidth, tileWidth, tileWidth);
-        this.getGraphics().drawImage(bufferedImage, tileWidth * x, tileWidth * y, this);
-    }
-
-    public void paint(Graphics g) {
-        for (int i = 0; i < tiles.length; i++) {
-            for (int j = 0; j < tiles[0].length; j++) {
-                g.drawImage(tiles[i][j], tileWidth * i, tileWidth * j, this);
-            }
-        }
-    }
-
-    public ImageDecoder getDecoder() {
-        return decoder;
-    }
-
-    public void setDecoder(ImageDecoder decoder) {
-        this.decoder = decoder;
-    }
-
-    public void stop(){
-        this.on=false;
-        socket.close();
-    }
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/WholeImageFilter.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/WholeImageFilter.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/WholeImageFilter.java	(working copy)
@@ -1,86 +0,0 @@
-/*
-Copyright 2006 Jerry Huxtable
-
-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 org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
-
-import java.awt.*;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.WritableRaster;
-
-/**
- * A filter which acts as a superclass for filters which need to have the whole image in memory
- * to do their stuff.
- */
-public abstract class WholeImageFilter extends AbstractBufferedImageOp {
-
-	/**
-     * The output image bounds.
-     */
-    protected Rectangle transformedSpace;
-
-	/**
-     * The input image bounds.
-     */
-	protected Rectangle originalSpace;
-	
-	/**
-	 * Construct a WholeImageFilter.
-	 */
-	public WholeImageFilter() {
-	}
-
-    public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
-        int width = src.getWidth();
-        int height = src.getHeight();
-		int type = src.getType();
-		WritableRaster srcRaster = src.getRaster();
-
-		originalSpace = new Rectangle(0, 0, width, height);
-		transformedSpace = new Rectangle(0, 0, width, height);
-		transformSpace(transformedSpace);
-
-        if ( dst == null ) {
-            ColorModel dstCM = src.getColorModel();
-			dst = new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(transformedSpace.width, transformedSpace.height), dstCM.isAlphaPremultiplied(), null);
-		}
-		WritableRaster dstRaster = dst.getRaster();
-
-		int[] inPixels = getRGB( src, 0, 0, width, height, null );
-		inPixels = filterPixels( width, height, inPixels, transformedSpace );
-		setRGB( dst, 0, 0, transformedSpace.width, transformedSpace.height, inPixels );
-
-        return dst;
-    }
-
-	/**
-     * Calculate output bounds for given input bounds.
-     * @param rect input and output rectangle
-     */
-	protected void transformSpace(Rectangle rect) {
-	}
-	
-	/**
-     * Actually filter the pixels.
-     * @param width the image width
-     * @param height the image height
-     * @param inPixels the image pixels
-     * @param transformedSpace the output bounds
-     * @return the output pixels
-     */
-	protected abstract int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace );
-}
-
Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/AbstractBufferedImageOp.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/AbstractBufferedImageOp.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/AbstractBufferedImageOp.java	(working copy)
@@ -1,98 +0,0 @@
-/*
-Copyright 2006 Jerry Huxtable
-
-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 org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
-
-import java.awt.*;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
-import java.awt.image.BufferedImageOp;
-import java.awt.image.ColorModel;
-
-/**
- * A convenience class which implements those methods of BufferedImageOp which are rarely changed.
- */
-public abstract class AbstractBufferedImageOp implements BufferedImageOp, Cloneable {
-
-    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
-        if ( dstCM == null )
-            dstCM = src.getColorModel();
-        return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()), dstCM.isAlphaPremultiplied(), null);
-    }
-    
-    public Rectangle2D getBounds2D( BufferedImage src ) {
-        return new Rectangle(0, 0, src.getWidth(), src.getHeight());
-    }
-    
-    public Point2D getPoint2D( Point2D srcPt, Point2D dstPt ) {
-        if ( dstPt == null )
-            dstPt = new Point2D.Double();
-        dstPt.setLocation( srcPt.getX(), srcPt.getY() );
-        return dstPt;
-    }
-
-    public RenderingHints getRenderingHints() {
-        return null;
-    }
-
-	/**
-	 * A convenience method for getting ARGB pixels from an image. This tries to avoid the performance
-	 * penalty of BufferedImage.getRGB unmanaging the image.
-     * @param image   a BufferedImage object
-     * @param x       the left edge of the pixel block
-     * @param y       the right edge of the pixel block
-     * @param width   the width of the pixel arry
-     * @param height  the height of the pixel arry
-     * @param pixels  the array to hold the returned pixels. May be null.
-     * @return the pixels
-     * @see #setRGB
-     */
-	public int[] getRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
-		int type = image.getType();
-		if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
-			return (int [])image.getRaster().getDataElements( x, y, width, height, pixels );
-		return image.getRGB( x, y, width, height, pixels, 0, width );
-    }
-
-	/**
-	 * A convenience method for setting ARGB pixels in an image. This tries to avoid the performance
-	 * penalty of BufferedImage.setRGB unmanaging the image.
-     * @param image   a BufferedImage object
-     * @param x       the left edge of the pixel block
-     * @param y       the right edge of the pixel block
-     * @param width   the width of the pixel arry
-     * @param height  the height of the pixel arry
-     * @param pixels  the array of pixels to set
-     * @see #getRGB
-	 */
-	public void setRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
-		int type = image.getType();
-		if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
-			image.getRaster().setDataElements( x, y, width, height, pixels );
-		else
-			image.setRGB( x, y, width, height, pixels, 0, width );
-    }
-
-	public Object clone() {
-		try {
-			return super.clone();
-		}
-		catch ( CloneNotSupportedException e ) {
-			return null;
-		}
-	}
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageDecoder.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageDecoder.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageDecoder.java	(working copy)
@@ -1,15 +0,0 @@
-package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
-
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-
-/**
- * Image Decoder Interface use this interface if you want to change the default decoder
- *
- * @author Thiago Rocha Camargo
- */
-public interface ImageDecoder {
-
-    public BufferedImage decode(ByteArrayInputStream stream) throws IOException;
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/OctTreeQuantizer.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/OctTreeQuantizer.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/OctTreeQuantizer.java	(working copy)
@@ -1,287 +0,0 @@
-/*
-Copyright 2006 Jerry Huxtable
-
-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 org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
-
-import java.io.PrintStream;
-import java.util.Vector;
-
-import org.jivesoftware.smackx.jingle.SmackLogger;
-
-/**
- * An image Quantizer based on the Octree algorithm. This is a very basic implementation
- * at present and could be much improved by picking the nodes to reduce more carefully 
- * (i.e. not completely at random) when I get the time.
- */
-public class OctTreeQuantizer implements Quantizer {
-
-	private static final SmackLogger LOGGER = SmackLogger.getLogger(OctTreeQuantizer.class);
-
-	/**
-	 * The greatest depth the tree is allowed to reach
-	 */
-	final static int MAX_LEVEL = 5;
-
-	/**
-	 * An Octtree node.
-	 */
-	class OctTreeNode {
-		int children;
-		int level;
-		OctTreeNode parent;
-		OctTreeNode leaf[] = new OctTreeNode[8];
-		boolean isLeaf;
-		int count;
-		int	totalRed;
-		int	totalGreen;
-		int	totalBlue;
-		int index;
-		
-		/**
-		 * A debugging method which prints the tree out.
-		 */
-		public void list(PrintStream s, int level) {
-			String indentStr = "";
-			for (int i = 0; i < level; i++)
-				indentStr += " ";
-			if (count == 0)
-				LOGGER.debug(indentStr + index + ": count=" + count);
-			else
-				LOGGER.debug(indentStr + index + ": count=" + count + " red=" + (totalRed/count) + " green=" + (totalGreen / count) + " blue=" + (totalBlue / count));
-			for (int i = 0; i < 8; i++)
-				if (leaf[i] != null)
-					leaf[i].list(s, level+2);
-		}
-	}
-
-	private int nodes = 0;
-	private OctTreeNode root;
-	private int reduceColors;
-	private int maximumColors;
-	private int colors = 0;
-	private Vector[] colorList;
-	
-	public OctTreeQuantizer() {
-		setup(256);
-		colorList = new Vector[MAX_LEVEL+1];
-		for (int i = 0; i < MAX_LEVEL+1; i++)
-			colorList[i] = new Vector();
-		root = new OctTreeNode();
-	}
-
-	/**
-	 * Initialize the quantizer. This should be called before adding any pixels.
-	 * @param numColors the number of colors we're quantizing to.
-	 */
-	public void setup(int numColors) {
-		maximumColors = numColors;
-		reduceColors = Math.max(512, numColors * 2);
-	}
-	
-	/**
-	 * Add pixels to the quantizer.
-	 * @param pixels the array of ARGB pixels
-	 * @param offset the offset into the array
-	 * @param count the count of pixels
-	 */
-	public void addPixels(int[] pixels, int offset, int count) {
-		for (int i = 0; i < count; i++) {
-			insertColor(pixels[i+offset]);
-			if (colors > reduceColors)
-				reduceTree(reduceColors);
-		}
-	}	
-
-    /**
-     * Get the color table index for a color.
-     * @param rgb the color
-     * @return the index
-     */
-	public int getIndexForColor(int rgb) {
-		int red = (rgb >> 16) & 0xff;
-		int green = (rgb >> 8) & 0xff;
-		int blue = rgb & 0xff;
-
-		OctTreeNode node = root;
-
-		for (int level = 0; level <= MAX_LEVEL; level++) {
-			OctTreeNode child;
-			int bit = 0x80 >> level;
-
-			int index = 0;
-			if ((red & bit) != 0)
-				index += 4;
-			if ((green & bit) != 0)
-				index += 2;
-			if ((blue & bit) != 0)
-				index += 1;
-
-			child = node.leaf[index];
-
-			if (child == null)
-				return node.index;
-			else if (child.isLeaf)
-				return child.index;
-			else
-				node = child;
-		}
-		LOGGER.debug("getIndexForColor failed");
-		return 0;
-	}
-
-	private void insertColor(int rgb) {
-		int red = (rgb >> 16) & 0xff;
-		int green = (rgb >> 8) & 0xff;
-		int blue = rgb & 0xff;
-
-		OctTreeNode node = root;
-
-//		LOGGER.debug("insertColor="+Integer.toHexString(rgb));
-		for (int level = 0; level <= MAX_LEVEL; level++) {
-			OctTreeNode child;
-			int bit = 0x80 >> level;
-
-			int index = 0;
-			if ((red & bit) != 0)
-				index += 4;
-			if ((green & bit) != 0)
-				index += 2;
-			if ((blue & bit) != 0)
-				index += 1;
-
-			child = node.leaf[index];
-
-			if (child == null) {
-				node.children++;
-
-				child = new OctTreeNode();
-				child.parent = node;
-				node.leaf[index] = child;
-				node.isLeaf = false;
-				nodes++;
-				colorList[level].addElement(child);
-
-				if (level == MAX_LEVEL) {
-					child.isLeaf = true;
-					child.count = 1;
-					child.totalRed = red;
-					child.totalGreen = green;
-					child.totalBlue = blue;
-					child.level = level;
-					colors++;
-					return;
-				}
-
-				node = child;
-			} else if (child.isLeaf) {
-				child.count++;
-				child.totalRed += red;
-				child.totalGreen += green;
-				child.totalBlue += blue;
-				return;
-			} else
-				node = child;
-		}
-		LOGGER.debug("insertColor failed");
-	}
-
-	private void reduceTree(int numColors) {
-		for (int level = MAX_LEVEL-1; level >= 0; level--) {
-			Vector v = colorList[level];
-			if (v != null && v.size() > 0) {
-				for (int j = 0; j < v.size(); j++) {
-					OctTreeNode node = (OctTreeNode)v.elementAt(j);
-					if (node.children > 0) {
-						for (int i = 0; i < 8; i++) {
-							OctTreeNode child = node.leaf[i];
-							if (child != null) {
-								if (!child.isLeaf)
-									LOGGER.debug("not a leaf!");
-								node.count += child.count;
-								node.totalRed += child.totalRed;
-								node.totalGreen += child.totalGreen;
-								node.totalBlue += child.totalBlue;
-								node.leaf[i] = null;
-								node.children--;
-								colors--;
-								nodes--;
-								colorList[level+1].removeElement(child);
-							}
-						}
-						node.isLeaf = true;
-						colors++;
-						if (colors <= numColors)
-							return;
-					}
-				}
-			}
-		}
-
-		LOGGER.debug("Unable to reduce the OctTree");
-	}
-
-    /**
-     * Build the color table.
-     * @return the color table
-     */
-	public int[] buildColorTable() {
-		int[] table = new int[colors];
-		buildColorTable(root, table, 0);
-		return table;
-	}
-	
-	/**
-	 * A quick way to use the quantizer. Just create a table the right size and pass in the pixels.
-     * @param inPixels the input colors
-     * @param table the output color table
-     */
-	public void buildColorTable(int[] inPixels, int[] table) {
-		int count = inPixels.length;
-		maximumColors = table.length;
-		for (int i = 0; i < count; i++) {
-			insertColor(inPixels[i]);
-			if (colors > reduceColors)
-				reduceTree(reduceColors);
-		}
-		if (colors > maximumColors)
-			reduceTree(maximumColors);
-		buildColorTable(root, table, 0);
-	}
-
-	private int buildColorTable(OctTreeNode node, int[] table, int index) {
-		if (colors > maximumColors)
-			reduceTree(maximumColors);
-
-		if (node.isLeaf) {
-			int count = node.count;
-			table[index] = 0xff000000 |
-				((node.totalRed/count) << 16) |
-				((node.totalGreen/count) << 8) |
-				node.totalBlue/count;
-			node.index = index++;
-		} else {
-			for (int i = 0; i < 8; i++) {
-				if (node.leaf[i] != null) {
-					node.index = index;
-					index = buildColorTable(node.leaf[i], table, index);
-				}
-			}
-		}
-		return index;
-	}
-	
-}
-
Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultDecoder.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultDecoder.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultDecoder.java	(working copy)
@@ -1,16 +0,0 @@
-package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
-
-import javax.imageio.ImageIO;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-
-/**
- * Implements a default PNG decoder.
- */
-public class DefaultDecoder implements ImageDecoder {
-
-    public BufferedImage decode(ByteArrayInputStream stream) throws IOException {
-        return ImageIO.read(stream);
-    }
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareMediaManager.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareMediaManager.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareMediaManager.java	(working copy)
@@ -1,115 +0,0 @@
-/**
- * $RCSfile: ScreenShareMediaManager.java,v $
- * $Revision: 1.3 $
- * $Date: 25/12/2006
- * <p/>
- * Copyright 2003-2006 Jive Software.
- * <p/>
- * All rights reserved. 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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.jivesoftware.smackx.jingle.mediaimpl.sshare;
-
-import org.jivesoftware.smackx.jingle.JingleSession;
-import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
-import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
-import org.jivesoftware.smackx.jingle.media.PayloadType;
-import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageDecoder;
-import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageEncoder;
-import org.jivesoftware.smackx.jingle.nat.JingleTransportManager;
-import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Implements a JingleMediaManager for ScreenSharing.
- * It currently uses an Audio payload Type. Which needs to be fixed in the next version.
- *
- * @author Thiago Camargo
- */
-
-public class ScreenShareMediaManager extends JingleMediaManager {
-
-    public static final String MEDIA_NAME = "ScreenShare";
-
-    private List<PayloadType> payloads = new ArrayList<PayloadType>();
-
-    private ImageDecoder decoder = null;
-    private ImageEncoder encoder = null;
-
-    public ScreenShareMediaManager(JingleTransportManager transportManager) {
-        super(transportManager);
-        setupPayloads();
-    }
-
-    /**
-     * Setup API supported Payloads
-     */
-    private void setupPayloads() {
-        payloads.add(new PayloadType.Audio(30, "sshare"));
-    }
-
-    /**
-     * Return all supported Payloads for this Manager.
-     *
-     * @return The Payload List
-     */
-    public List<PayloadType> getPayloads() {
-        return payloads;
-    }
-
-    /**
-     * Returns a new JingleMediaSession
-     *
-     * @param payloadType payloadType
-     * @param remote      remote Candidate
-     * @param local       local Candidate
-     * @return JingleMediaSession JingleMediaSession
-     */
-    public JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) {
-        ScreenShareSession session = null;
-        session = new ScreenShareSession(payloadType, remote, local, "Screen", jingleSession);
-        if (encoder != null) {
-            session.setEncoder(encoder);
-        }
-        if (decoder != null) {
-            session.setDecoder(decoder);
-        }
-        return session;
-    }
-
-    public PayloadType getPreferredPayloadType() {
-        return super.getPreferredPayloadType();
-    }
-
-    public ImageDecoder getDecoder() {
-        return decoder;
-    }
-
-    public void setDecoder(ImageDecoder decoder) {
-        this.decoder = decoder;
-    }
-
-    public ImageEncoder getEncoder() {
-        return encoder;
-    }
-
-    public void setEncoder(ImageEncoder encoder) {
-        this.encoder = encoder;
-    }
-    
-    public  String getName() {
-        return MEDIA_NAME;
-    }
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/multi/MultiMediaManager.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/multi/MultiMediaManager.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/multi/MultiMediaManager.java	(working copy)
@@ -1,106 +0,0 @@
-/**
- * $RCSfile: MultiMediaManager.java,v $
- * $Revision: 1.3 $
- * $Date: 25/12/2006
- * <p/>
- * Copyright 2003-2006 Jive Software.
- * <p/>
- * All rights reserved. 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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.jivesoftware.smackx.jingle.mediaimpl.multi;
-
-import org.jivesoftware.smackx.jingle.JingleSession;
-import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
-import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
-import org.jivesoftware.smackx.jingle.media.PayloadType;
-import org.jivesoftware.smackx.jingle.nat.JingleTransportManager;
-import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Implements a MultiMediaManager using other JingleMediaManager implementations.
- * It supports every Codecs that JingleMediaManagers added has.
- *
- * @author Thiago Camargo
- */
-
-public class MultiMediaManager extends JingleMediaManager {
-
-    public static final String MEDIA_NAME = "Multi";
-
-    private List<JingleMediaManager> managers = new ArrayList<JingleMediaManager>();
-
-    private PayloadType preferredPayloadType = null;
-
-    public MultiMediaManager(JingleTransportManager transportManager) {
-        super(transportManager);
-    }
-
-    public void addMediaManager(JingleMediaManager manager) {
-        managers.add(manager);
-    }
-
-    public void removeMediaManager(JingleMediaManager manager) {
-        managers.remove(manager);
-    }
-
-    /**
-     * Return all supported Payloads for this Manager.
-     *
-     * @return The Payload List
-     */
-    public List<PayloadType> getPayloads() {
-        List<PayloadType> list = new ArrayList<PayloadType>();
-        if (preferredPayloadType != null) list.add(preferredPayloadType);
-        for (JingleMediaManager manager : managers) {
-            for (PayloadType payloadType : manager.getPayloads()) {
-                if (!list.contains(payloadType) && !payloadType.equals(preferredPayloadType))
-                    list.add(payloadType);
-            }
-        }
-        return list;
-    }
-
-    /**
-     * Returns a new JingleMediaSession
-     *
-     * @param payloadType payloadType
-     * @param remote      remote Candidate
-     * @param local       local Candidate
-     * @return JingleMediaSession JingleMediaSession
-     */
-    public JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) {
-        for (JingleMediaManager manager : managers) {
-            if (manager.getPayloads().contains(payloadType)) {
-                return manager.createMediaSession(payloadType, remote, local, jingleSession);
-            }
-        }
-        return null;
-    }
-
-    public PayloadType getPreferredPayloadType() {
-        if (preferredPayloadType != null) return preferredPayloadType;
-        return super.getPreferredPayloadType();
-    }
-
-    public void setPreferredPayloadType(PayloadType preferredPayloadType) {
-        this.preferredPayloadType = preferredPayloadType;
-    }
-    
-    public  String getName() {
-        return MEDIA_NAME;
-    }
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java	(working copy)
@@ -1,165 +0,0 @@
-/**
- * $RCSfile: AudioMediaSession.java,v $
- * $Revision: 1.1 $
- * $Date: 08/11/2006
- * <p/>
- * Copyright 2003-2006 Jive Software.
- * <p/>
- * All rights reserved. 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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.jivesoftware.smackx.jingle.mediaimpl.jmf;
-
-import java.io.IOException;
-import java.net.ServerSocket;
-
-import javax.media.MediaLocator;
-
-import org.jivesoftware.smackx.jingle.JingleSession;
-import org.jivesoftware.smackx.jingle.SmackLogger;
-import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
-import org.jivesoftware.smackx.jingle.media.PayloadType;
-import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
-
-/**
- * This Class implements a complete JingleMediaSession.
- * It sould be used to transmit and receive audio captured from the Mic.
- * This Class should be automaticly controlled by JingleSession.
- * But you could also use in any VOIP application.
- * For better NAT Traversal support this implementation don't support only receive or only transmit.
- * To receive you MUST transmit. So the only implemented and functionally methods are startTransmit() and stopTransmit()
- *
- * @author Thiago Camargo
- */
-public class AudioMediaSession extends JingleMediaSession {
-
-	private static final SmackLogger LOGGER = SmackLogger.getLogger(AudioMediaSession.class);
-
-	private AudioChannel audioChannel;
-
-    /**
-     * Creates a org.jivesoftware.jingleaudio.jmf.AudioMediaSession with defined payload type, remote and local candidates
-     *
-     * @param payloadType Payload of the jmf
-     * @param remote      the remote information. The candidate that the jmf will be sent to.
-     * @param local       the local information. The candidate that will receive the jmf
-     * @param locator     media locator
-     */
-    public AudioMediaSession(final PayloadType payloadType, final TransportCandidate remote,
-            final TransportCandidate local, String locator, JingleSession jingleSession) {
-        super(payloadType, remote, local, locator==null?"dsound://":locator,jingleSession);
-        initialize();
-    }
-
-    /**
-     * Initialize the Audio Channel to make it able to send and receive audio
-     */
-    public void initialize() {
-
-        String ip;
-        String localIp;
-        int localPort;
-        int remotePort;
-
-        if (this.getLocal().getSymmetric() != null) {
-            ip = this.getLocal().getIp();
-            localIp = this.getLocal().getLocalIp();
-            localPort = getFreePort();
-            remotePort = this.getLocal().getSymmetric().getPort();
-
-            LOGGER.debug(this.getLocal().getConnection() + " " + ip + ": " + localPort + "->" + remotePort);
-
-        }
-        else {
-            ip = this.getRemote().getIp();
-            localIp = this.getLocal().getLocalIp();
-            localPort = this.getLocal().getPort();
-            remotePort = this.getRemote().getPort();
-        }
-
-        audioChannel = new AudioChannel(new MediaLocator(this.getMediaLocator()), localIp, ip, localPort, remotePort, AudioFormatUtils.getAudioFormat(this.getPayloadType()),this);
-    }
-
-    /**
-     * Starts transmission and for NAT Traversal reasons start receiving also.
-     */
-    public void startTrasmit() {
-        audioChannel.start();
-    }
-
-    /**
-     * Set transmit activity. If the active is true, the instance should trasmit.
-     * If it is set to false, the instance should pause transmit.
-     *
-     * @param active active state
-     */
-    public void setTrasmit(boolean active) {
-        audioChannel.setTrasmit(active);
-    }
-
-    /**
-     * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
-     */
-    public void startReceive() {
-        // Do nothing
-    }
-
-    /**
-     * Stops transmission and for NAT Traversal reasons stop receiving also.
-     */
-    public void stopTrasmit() {
-        if (audioChannel != null)
-            audioChannel.stop();
-    }
-
-    /**
-     * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
-     */
-    public void stopReceive() {
-        // Do nothing
-    }
-
-    /**
-     * Obtain a free port we can use.
-     *
-     * @return A free port number.
-     */
-    protected int getFreePort() {
-        ServerSocket ss;
-        int freePort = 0;
-
-        for (int i = 0; i < 10; i++) {
-            freePort = (int) (10000 + Math.round(Math.random() * 10000));
-            freePort = freePort % 2 == 0 ? freePort : freePort + 1;
-            try {
-                ss = new ServerSocket(freePort);
-                freePort = ss.getLocalPort();
-                ss.close();
-                return freePort;
-            }
-            catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
-        try {
-            ss = new ServerSocket(0);
-            freePort = ss.getLocalPort();
-            ss.close();
-        }
-        catch (IOException e) {
-            e.printStackTrace();
-        }
-        return freePort;
-    }
-
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java	(working copy)
@@ -1,171 +0,0 @@
-/**
- * $RCSfile: AudioReceiver.java,v $
- * $Revision: 1.1 $
- * $Date: 08/11/2006
- * <p/>
- * Copyright 2003-2006 Jive Software.
- * <p/>
- * All rights reserved. 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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.jivesoftware.smackx.jingle.mediaimpl.jmf;
-
-import javax.media.ControllerErrorEvent;
-import javax.media.ControllerEvent;
-import javax.media.ControllerListener;
-import javax.media.Player;
-import javax.media.RealizeCompleteEvent;
-import javax.media.protocol.DataSource;
-import javax.media.rtp.Participant;
-import javax.media.rtp.RTPControl;
-import javax.media.rtp.ReceiveStream;
-import javax.media.rtp.ReceiveStreamListener;
-import javax.media.rtp.SessionListener;
-import javax.media.rtp.event.ByeEvent;
-import javax.media.rtp.event.NewParticipantEvent;
-import javax.media.rtp.event.NewReceiveStreamEvent;
-import javax.media.rtp.event.ReceiveStreamEvent;
-import javax.media.rtp.event.RemotePayloadChangeEvent;
-import javax.media.rtp.event.SessionEvent;
-import javax.media.rtp.event.StreamMappedEvent;
-
-import org.jivesoftware.smackx.jingle.SmackLogger;
-import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
-
-/**
- * This class implements receive methods and listeners to be used in AudioChannel
- *
- * @author Thiago Camargo
- */
-public class AudioReceiver implements ReceiveStreamListener, SessionListener,
-        ControllerListener {
-
-	private static final SmackLogger LOGGER = SmackLogger.getLogger(AudioReceiver.class);
-
-	boolean dataReceived = false;
-
-    Object dataSync;
-    JingleMediaSession jingleMediaSession;
-
-    public AudioReceiver(final Object dataSync, final JingleMediaSession jingleMediaSession) {
-        this.dataSync = dataSync;
-        this.jingleMediaSession = jingleMediaSession;
-    }
-
-    /**
-     * JingleSessionListener.
-     */
-    public synchronized void update(SessionEvent evt) {
-        if (evt instanceof NewParticipantEvent) {
-            Participant p = ((NewParticipantEvent) evt).getParticipant();
-            LOGGER.error("  - A new participant had just joined: " + p.getCNAME());
-        }
-    }
-
-    /**
-     * ReceiveStreamListener
-     */
-    public synchronized void update(ReceiveStreamEvent evt) {
-
-        Participant participant = evt.getParticipant();    // could be null.
-        ReceiveStream stream = evt.getReceiveStream();  // could be null.
-
-        if (evt instanceof RemotePayloadChangeEvent) {
-            LOGGER.error("  - Received an RTP PayloadChangeEvent.");
-            LOGGER.error("Sorry, cannot handle payload change.");
-
-        }
-        else if (evt instanceof NewReceiveStreamEvent) {
-
-            try {
-                stream = evt.getReceiveStream();
-                DataSource ds = stream.getDataSource();
-
-                // Find out the formats.
-                RTPControl ctl = (RTPControl) ds.getControl("javax.jmf.rtp.RTPControl");
-                if (ctl != null) {
-                    LOGGER.error("  - Recevied new RTP stream: " + ctl.getFormat());
-                }
-                else
-                    LOGGER.error("  - Recevied new RTP stream");
-
-                if (participant == null)
-                    LOGGER.error("      The sender of this stream had yet to be identified.");
-                else {
-                    LOGGER.error("      The stream comes from: " + participant.getCNAME());
-                }
-
-                // create a player by passing datasource to the Media Manager
-                Player p = javax.media.Manager.createPlayer(ds);
-                if (p == null)
-                    return;
-
-                p.addControllerListener(this);
-                p.realize();
-                jingleMediaSession.mediaReceived(participant != null ? participant.getCNAME() : "");
-
-                // Notify intialize() that a new stream had arrived.
-                synchronized (dataSync) {
-                    dataReceived = true;
-                    dataSync.notifyAll();
-                }
-
-            }
-            catch (Exception e) {
-                LOGGER.error("NewReceiveStreamEvent exception " + e.getMessage());
-                return;
-            }
-
-        }
-        else if (evt instanceof StreamMappedEvent) {
-
-            if (stream != null && stream.getDataSource() != null) {
-                DataSource ds = stream.getDataSource();
-                // Find out the formats.
-                RTPControl ctl = (RTPControl) ds.getControl("javax.jmf.rtp.RTPControl");
-                LOGGER.error("  - The previously unidentified stream ");
-                if (ctl != null)
-                    LOGGER.error("      " + ctl.getFormat());
-                LOGGER.error("      had now been identified as sent by: " + participant.getCNAME());
-            }
-        }
-        else if (evt instanceof ByeEvent) {
-
-            LOGGER.error("  - Got \"bye\" from: " + participant.getCNAME());
-
-        }
-
-    }
-
-    /**
-     * ControllerListener for the Players.
-     */
-    public synchronized void controllerUpdate(ControllerEvent ce) {
-
-        Player p = (Player) ce.getSourceController();
-
-        if (p == null)
-            return;
-
-        // Get this when the internal players are realized.
-        if (ce instanceof RealizeCompleteEvent) {
-            p.start();
-        }
-
-        if (ce instanceof ControllerErrorEvent) {
-            p.removeControllerListener(this);
-            LOGGER.error("Receiver internal error: " + ce);
-        }
-
-    }
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/JmfMediaManager.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/jmf/JmfMediaManager.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/JmfMediaManager.java	(working copy)
@@ -1,170 +0,0 @@
-/**
- * $RCSfile: JmfMediaManager.java,v $
- * $Revision: 1.3 $
- * $Date: 08/11/2006
- * <p/>
- * Copyright 2003-2006 Jive Software.
- * <p/>
- * All rights reserved. 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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.jivesoftware.smackx.jingle.mediaimpl.jmf;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.jivesoftware.smackx.jingle.JingleSession;
-import org.jivesoftware.smackx.jingle.SmackLogger;
-import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
-import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
-import org.jivesoftware.smackx.jingle.media.PayloadType;
-import org.jivesoftware.smackx.jingle.mediaimpl.JMFInit;
-import org.jivesoftware.smackx.jingle.nat.JingleTransportManager;
-import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
-
-/**
- * Implements a jingleMediaManager using JMF based API.
- * It supports GSM and G723 codecs.
- * <i>This API only currently works on windows and Mac.</i>
- *
- * @author Thiago Camargo
- */
-public class JmfMediaManager extends JingleMediaManager {
-
-	private static final SmackLogger LOGGER = SmackLogger.getLogger(JmfMediaManager.class);
-
-	public static final String MEDIA_NAME = "JMF";
-
-    
-    private List<PayloadType> payloads = new ArrayList<PayloadType>();
-    private String mediaLocator = null;
-
-    /**
-     * Creates a Media Manager instance
-     */
-    public JmfMediaManager(JingleTransportManager transportManager) {
-        super(transportManager);
-        setupPayloads();
-    }
-
-    /**
-     * Creates a Media Manager instance
-     *
-     * @param mediaLocator Media Locator
-     */
-    public JmfMediaManager(String mediaLocator, JingleTransportManager transportManager) {
-        super(transportManager);
-        this.mediaLocator = mediaLocator;
-        setupPayloads();
-    }
-
-    /**
-     * Returns a new jingleMediaSession
-     *
-     * @param payloadType payloadType
-     * @param remote      remote Candidate
-     * @param local       local Candidate
-     * @return JingleMediaSession
-     */
-    public JingleMediaSession createMediaSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) {
-        return new AudioMediaSession(payloadType, remote, local, mediaLocator, jingleSession);
-    }
-
-    /**
-     * Setup API supported Payloads
-     */
-    private void setupPayloads() {
-        payloads.add(new PayloadType.Audio(3, "gsm"));
-        payloads.add(new PayloadType.Audio(4, "g723"));
-        payloads.add(new PayloadType.Audio(0, "PCMU", 16000));
-    }
-
-    /**
-     * Return all supported Payloads for this Manager
-     *
-     * @return The Payload List
-     */
-    public List<PayloadType> getPayloads() {
-        return payloads;
-    }
-
-    /**
-     * Return the media locator or null if not defined
-     *
-     * @return media locator
-     */
-    public String getMediaLocator() {
-        return mediaLocator;
-    }
-
-    /**
-     * Set the media locator
-     *
-     * @param mediaLocator media locator or null to use default
-     */
-    public void setMediaLocator(String mediaLocator) {
-        this.mediaLocator = mediaLocator;
-    }
-
-    /**
-     * Runs JMFInit the first time the application is started so that capture
-     * devices are properly detected and initialized by JMF.
-     */
-    public static void setupJMF() {
-        // .jmf is the place where we store the jmf.properties file used
-        // by JMF. if the directory does not exist or it does not contain
-        // a jmf.properties file. or if the jmf.properties file has 0 length
-        // then this is the first time we're running and should continue to
-        // with JMFInit
-        String homeDir = System.getProperty("user.home");
-        File jmfDir = new File(homeDir, ".jmf");
-        String classpath = System.getProperty("java.class.path");
-        classpath += System.getProperty("path.separator")
-                + jmfDir.getAbsolutePath();
-        System.setProperty("java.class.path", classpath);
-
-        if (!jmfDir.exists())
-            jmfDir.mkdir();
-
-        File jmfProperties = new File(jmfDir, "jmf.properties");
-
-        if (!jmfProperties.exists()) {
-            try {
-                jmfProperties.createNewFile();
-            }
-            catch (IOException ex) {
-                LOGGER.debug("Failed to create jmf.properties");
-                ex.printStackTrace();
-            }
-        }
-
-        // if we're running on linux checkout that libjmutil.so is where it
-        // should be and put it there.
-        runLinuxPreInstall();
-
-        //if (jmfProperties.length() == 0) {
-        new JMFInit(null, false);
-        //}
-
-    }
-
-    private static void runLinuxPreInstall() {
-        // @TODO Implement Linux Pre-Install
-    }
-    
-    public  String getName() {
-        return MEDIA_NAME;
-    }
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java	(working copy)
@@ -1,553 +0,0 @@
-/**
- * $RCSfile: AudioChannel.java,v $
- * $Revision: 1.1 $
- * $Date: 08/11/2006
- * <p/>
- * Copyright 2003-2006 Jive Software.
- * <p/>
- * All rights reserved. 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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.jivesoftware.smackx.jingle.mediaimpl.jmf;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.media.Codec;
-import javax.media.Controller;
-import javax.media.ControllerClosedEvent;
-import javax.media.ControllerEvent;
-import javax.media.ControllerListener;
-import javax.media.Format;
-import javax.media.MediaLocator;
-import javax.media.NoProcessorException;
-import javax.media.Processor;
-import javax.media.UnsupportedPlugInException;
-import javax.media.control.BufferControl;
-import javax.media.control.PacketSizeControl;
-import javax.media.control.TrackControl;
-import javax.media.format.AudioFormat;
-import javax.media.protocol.ContentDescriptor;
-import javax.media.protocol.DataSource;
-import javax.media.protocol.PushBufferDataSource;
-import javax.media.protocol.PushBufferStream;
-import javax.media.rtp.InvalidSessionAddressException;
-import javax.media.rtp.RTPManager;
-import javax.media.rtp.SendStream;
-import javax.media.rtp.SessionAddress;
-
-import org.jivesoftware.smackx.jingle.SmackLogger;
-import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
-
-/**
- * An Easy to use Audio Channel implemented using JMF.
- * It sends and receives jmf for and from desired IPs and ports.
- * Also has a rport Symetric behavior for better NAT Traversal.
- * It send data from a defined port and receive data in the same port, making NAT binds easier.
- * <p/>
- * Send from portA to portB and receive from portB in portA.
- * <p/>
- * Sending
- * portA ---> portB
- * <p/>
- * Receiving
- * portB ---> portA
- * <p/>
- * <i>Transmit and Receive are interdependents. To receive you MUST trasmit. </i>
- *
- * @author Thiago Camargo
- */
-public class AudioChannel {
-
-	private static final SmackLogger LOGGER = SmackLogger.getLogger(AudioChannel.class);
-	
-	private MediaLocator locator;
-    private String localIpAddress;
-    private String remoteIpAddress;
-    private int localPort;
-    private int portBase;
-    private Format format;
-
-    private Processor processor = null;
-    private RTPManager rtpMgrs[];
-    private DataSource dataOutput = null;
-    private AudioReceiver audioReceiver;
-
-    private List<SendStream> sendStreams = new ArrayList<SendStream>();
-
-    private JingleMediaSession jingleMediaSession;
-
-    private boolean started = false;
-
-    /**
-     * Creates an Audio Channel for a desired jmf locator. For instance: new MediaLocator("dsound://")
-     *
-     * @param locator         media locator
-     * @param localIpAddress  local IP address
-     * @param remoteIpAddress remote IP address
-     * @param localPort       local port number
-     * @param remotePort      remote port number
-     * @param format          audio format
-     */
-    public AudioChannel(MediaLocator locator,
-            String localIpAddress,
-            String remoteIpAddress,
-            int localPort,
-            int remotePort,
-            Format format, JingleMediaSession jingleMediaSession) {
-
-        this.locator = locator;
-        this.localIpAddress = localIpAddress;
-        this.remoteIpAddress = remoteIpAddress;
-        this.localPort = localPort;
-        this.portBase = remotePort;
-        this.format = format;
-        this.jingleMediaSession = jingleMediaSession;
-    }
-
-    /**
-     * Starts the transmission. Returns null if transmission started ok.
-     * Otherwise it returns a string with the reason why the setup failed.
-     * Starts receive also.
-     *
-     * @return result description
-     */
-    public synchronized String start() {
-        if (started) return null;
-
-        // Create a processor for the specified jmf locator
-        String result = createProcessor();
-        if (result != null) {
-            started = false;
-        }
-
-        // Create an RTP session to transmit the output of the
-        // processor to the specified IP address and port no.
-        result = createTransmitter();
-        if (result != null) {
-            processor.close();
-            processor = null;
-            started = false;
-        }
-        else {
-            started = true;
-        }
-
-        // Start the transmission
-        processor.start();
-
-        return null;
-    }
-
-    /**
-     * Stops the transmission if already started.
-     * Stops the receiver also.
-     */
-    public void stop() {
-        if (!started) return;
-        synchronized (this) {
-            try {
-                started = false;
-                if (processor != null) {
-                    processor.stop();
-                    processor = null;
-
-                    for (RTPManager rtpMgr : rtpMgrs) {
-                        rtpMgr.removeReceiveStreamListener(audioReceiver);
-                        rtpMgr.removeSessionListener(audioReceiver);
-                        rtpMgr.removeTargets("Session ended.");
-                        rtpMgr.dispose();
-                    }
-
-                    sendStreams.clear();
-
-                }
-            }
-            catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    private String createProcessor() {
-        if (locator == null)
-            return "Locator is null";
-
-        DataSource ds;
-
-        try {
-            ds = javax.media.Manager.createDataSource(locator);
-        }
-        catch (Exception e) {
-            // Try JavaSound Locator as a last resort
-            try {
-                ds = javax.media.Manager.createDataSource(new MediaLocator("javasound://"));
-            }
-            catch (Exception ee) {
-                return "Couldn't create DataSource";
-            }
-        }
-
-        // Try to create a processor to handle the input jmf locator
-        try {
-            processor = javax.media.Manager.createProcessor(ds);
-        }
-        catch (NoProcessorException npe) {
-            npe.printStackTrace();
-            return "Couldn't create processor";
-        }
-        catch (IOException ioe) {
-            ioe.printStackTrace();
-            return "IOException creating processor";
-        }
-
-        // Wait for it to configure
-        boolean result = waitForState(processor, Processor.Configured);
-        if (!result){
-            return "Couldn't configure processor";
-        }
-        
-        // Get the tracks from the processor
-        TrackControl[] tracks = processor.getTrackControls();
-
-        // Do we have atleast one track?
-        if (tracks == null || tracks.length < 1){
-            return "Couldn't find tracks in processor";
-        }
-
-        // Set the output content descriptor to RAW_RTP
-        // This will limit the supported formats reported from
-        // Track.getSupportedFormats to only valid RTP formats.
-        ContentDescriptor cd = new ContentDescriptor(ContentDescriptor.RAW_RTP);
-        processor.setContentDescriptor(cd);
-
-        Format supported[];
-        Format chosen = null;
-        boolean atLeastOneTrack = false;
-
-        // Program the tracks.
-        for (int i = 0; i < tracks.length; i++) {
-            if (tracks[i].isEnabled()) {
-
-                supported = tracks[i].getSupportedFormats();
-
-                if (supported.length > 0) {
-                    for (Format format : supported) {
-                        if (format instanceof AudioFormat) {
-                            if (this.format.matches(format))
-                                chosen = format;
-                        }
-                    }
-                    if (chosen != null) {
-                        tracks[i].setFormat(chosen);
-                        LOGGER.error("Track " + i + " is set to transmit as:");
-                        LOGGER.error("  " + chosen);
-
-                        if (tracks[i].getFormat() instanceof AudioFormat) {
-                            int packetRate = 20;
-                            PacketSizeControl pktCtrl = (PacketSizeControl) processor.getControl(PacketSizeControl.class.getName());
-                            if (pktCtrl != null) {
-                                try {
-                                    pktCtrl.setPacketSize(getPacketSize(tracks[i].getFormat(), packetRate));
-                                }
-                                catch (IllegalArgumentException e) {
-                                    pktCtrl.setPacketSize(80);
-                                    // Do nothing
-                                }
-                            }
-
-                            if (tracks[i].getFormat().getEncoding().equals(AudioFormat.ULAW_RTP)) {
-                                Codec codec[] = new Codec[3];
-
-                                codec[0] = new com.ibm.media.codec.audio.rc.RCModule();
-                                codec[1] = new com.ibm.media.codec.audio.ulaw.JavaEncoder();
-                                codec[2] = new com.sun.media.codec.audio.ulaw.Packetizer();
-                                ((com.sun.media.codec.audio.ulaw.Packetizer) codec
-                                        [2]).setPacketSize(160);
-
-                                try {
-                                    tracks[i].setCodecChain(codec);
-                                }
-                                catch (UnsupportedPlugInException e) {
-                                    e.printStackTrace();
-                                }
-                            }
-
-                        }
-
-                        atLeastOneTrack = true;
-                    }
-                    else
-                        tracks[i].setEnabled(false);
-                }
-                else
-                    tracks[i].setEnabled(false);
-            }
-        }
-
-        if (!atLeastOneTrack)
-            return "Couldn't set any of the tracks to a valid RTP format";
-
-        result = waitForState(processor, Controller.Realized);
-        if (!result)
-            return "Couldn't realize processor";
-
-        // Get the output data source of the processor
-        dataOutput = processor.getDataOutput();
-
-        return null;
-    }
-
-    /**
-     * Get the best packet size for a given codec and a codec rate
-     *
-     * @param codecFormat
-     * @param milliseconds
-     * @return
-     * @throws IllegalArgumentException
-     */
-    private int getPacketSize(Format codecFormat, int milliseconds) throws IllegalArgumentException {
-        String encoding = codecFormat.getEncoding();
-        if (encoding.equalsIgnoreCase(AudioFormat.GSM) ||
-                encoding.equalsIgnoreCase(AudioFormat.GSM_RTP)) {
-            return milliseconds * 4; // 1 byte per millisec
-        }
-        else if (encoding.equalsIgnoreCase(AudioFormat.ULAW) ||
-                encoding.equalsIgnoreCase(AudioFormat.ULAW_RTP)) {
-            return milliseconds * 8;
-        }
-        else {
-            throw new IllegalArgumentException("Unknown codec type");
-        }
-    }
-
-    /**
-     * Use the RTPManager API to create sessions for each jmf
-     * track of the processor.
-     *
-     * @return description
-     */
-    private String createTransmitter() {
-
-        // Cheated.  Should have checked the type.
-        PushBufferDataSource pbds = (PushBufferDataSource) dataOutput;
-        PushBufferStream pbss[] = pbds.getStreams();
-
-        rtpMgrs = new RTPManager[pbss.length];
-        SessionAddress localAddr, destAddr;
-        InetAddress ipAddr;
-        SendStream sendStream;
-        audioReceiver = new AudioReceiver(this, jingleMediaSession);
-        int port;
-
-        for (int i = 0; i < pbss.length; i++) {
-            try {
-                rtpMgrs[i] = RTPManager.newInstance();
-
-                port = portBase + 2 * i;
-                ipAddr = InetAddress.getByName(remoteIpAddress);
-
-                localAddr = new SessionAddress(InetAddress.getByName(this.localIpAddress),
-                        localPort);
-
-                destAddr = new SessionAddress(ipAddr, port);
-
-                rtpMgrs[i].addReceiveStreamListener(audioReceiver);
-                rtpMgrs[i].addSessionListener(audioReceiver);
-
-                BufferControl bc = (BufferControl) rtpMgrs[i].getControl("javax.media.control.BufferControl");
-                if (bc != null) {
-                    int bl = 160;
-                    bc.setBufferLength(bl);
-                }
-
-                try {
-
-                    rtpMgrs[i].initialize(localAddr);
-
-                }
-                catch (InvalidSessionAddressException e) {
-                    // In case the local address is not allowed to read, we user another local address
-                    SessionAddress sessAddr = new SessionAddress();
-                    localAddr = new SessionAddress(sessAddr.getDataAddress(),
-                            localPort);
-                    rtpMgrs[i].initialize(localAddr);
-                }
-
-                rtpMgrs[i].addTarget(destAddr);
-
-                LOGGER.error("Created RTP session at " + localPort + " to: " + remoteIpAddress + " " + port);
-
-                sendStream = rtpMgrs[i].createSendStream(dataOutput, i);
-
-                sendStreams.add(sendStream);
-
-                sendStream.start();
-
-            }
-            catch (Exception e) {
-                e.printStackTrace();
-                return e.getMessage();
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Set transmit activity. If the active is true, the instance should trasmit.
-     * If it is set to false, the instance should pause transmit.
-     *
-     * @param active active state
-     */
-    public void setTrasmit(boolean active) {
-        for (SendStream sendStream : sendStreams) {
-            try {
-                if (active) {
-                    sendStream.start();
-                    LOGGER.debug("START");
-                }
-                else {
-                    sendStream.stop();
-                    LOGGER.debug("STOP");
-                }
-            }
-            catch (IOException e) {
-                e.printStackTrace();
-            }
-
-        }
-    }
-
-    /**
-     * *************************************************************
-     * Convenience methods to handle processor's state changes.
-     * **************************************************************
-     */
-
-    private Integer stateLock = 0;
-    private boolean failed = false;
-
-    Integer getStateLock() {
-        return stateLock;
-    }
-
-    void setFailed() {
-        failed = true;
-    }
-
-    private synchronized boolean waitForState(Processor p, int state) {
-        p.addControllerListener(new StateListener());
-        failed = false;
-
-        // Call the required method on the processor
-        if (state == Processor.Configured) {
-            p.configure();
-        }
-        else if (state == Processor.Realized) {
-            p.realize();
-        }
-
-        // Wait until we get an event that confirms the
-        // success of the method, or a failure event.
-        // See StateListener inner class
-        while (p.getState() < state && !failed) {
-            synchronized (getStateLock()) {
-                try {
-                    getStateLock().wait();
-                }
-                catch (InterruptedException ie) {
-                    return false;
-                }
-            }
-        }
-
-        return !failed;
-    }
-
-    /**
-     * *************************************************************
-     * Inner Classes
-     * **************************************************************
-     */
-
-    class StateListener implements ControllerListener {
-
-        public void controllerUpdate(ControllerEvent ce) {
-
-            // If there was an error during configure or
-            // realize, the processor will be closed
-            if (ce instanceof ControllerClosedEvent)
-                setFailed();
-
-            // All controller events, send a notification
-            // to the waiting thread in waitForState method.
-            if (ce != null) {
-                synchronized (getStateLock()) {
-                    getStateLock().notifyAll();
-                }
-            }
-        }
-    }
-
-    public static void main(String args[]) {
-
-        InetAddress localhost;
-        try {
-            localhost = InetAddress.getLocalHost();
-
-            AudioChannel audioChannel0 = new AudioChannel(new MediaLocator("javasound://8000"), localhost.getHostAddress(), localhost.getHostAddress(), 7002, 7020, new AudioFormat(AudioFormat.GSM_RTP), null);
-            AudioChannel audioChannel1 = new AudioChannel(new MediaLocator("javasound://8000"), localhost.getHostAddress(), localhost.getHostAddress(), 7020, 7002, new AudioFormat(AudioFormat.GSM_RTP), null);
-
-            audioChannel0.start();
-            audioChannel1.start();
-
-            try {
-                Thread.sleep(5000);
-            }
-            catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-
-            audioChannel0.setTrasmit(false);
-            audioChannel1.setTrasmit(false);
-
-            try {
-                Thread.sleep(5000);
-            }
-            catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-
-            audioChannel0.setTrasmit(true);
-            audioChannel1.setTrasmit(true);
-
-            try {
-                Thread.sleep(5000);
-            }
-            catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-
-            audioChannel0.stop();
-            audioChannel1.stop();
-
-        }
-        catch (UnknownHostException e) {
-            e.printStackTrace();
-        }
-
-    }
-}
\ No newline at end of file
Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioFormatUtils.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioFormatUtils.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioFormatUtils.java	(working copy)
@@ -1,55 +0,0 @@
-/**
- * $RCSfile: AudioFormatUtils.java,v $
- * $Revision: 1.1 $
- * $Date: 08/11/2006
- * <p/>
- * Copyright 2003-2006 Jive Software.
- * <p/>
- * All rights reserved. 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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.jivesoftware.smackx.jingle.mediaimpl.jmf;
-
-import org.jivesoftware.smackx.jingle.media.PayloadType;
-
-import javax.media.format.AudioFormat;
-
-/**
- * Audio Format Utils.
- *
- * @author Thiago Camargo
- */
-public class AudioFormatUtils {
-
-    /**
-     * Return a JMF AudioFormat for a given Jingle Payload type.
-     * Return null if the payload is not supported by this jmf API.
-     *
-     * @param payloadtype payloadtype
-     * @return correspondent audioType
-     */
-    public static AudioFormat getAudioFormat(PayloadType payloadtype) {
-
-        switch (payloadtype.getId()) {
-            case 0:
-                return new AudioFormat(AudioFormat.ULAW_RTP);
-            case 3:
-                return new AudioFormat(AudioFormat.GSM_RTP);
-            case 4:
-                return new AudioFormat(AudioFormat.G723_RTP);
-            default:
-                return null;
-        }
-
-    }
-
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/jspeex/SpeexMediaManager.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/jspeex/SpeexMediaManager.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/jspeex/SpeexMediaManager.java	(working copy)
@@ -1,134 +0,0 @@
-/**
- * $RCSfile: SpeexMediaManager.java,v $
- * $Revision: 1.3 $
- * $Date: 25/12/2006
- * <p/>
- * Copyright 2003-2006 Jive Software.
- * <p/>
- * All rights reserved. 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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.jivesoftware.smackx.jingle.mediaimpl.jspeex;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.jivesoftware.smackx.jingle.JingleSession;
-import org.jivesoftware.smackx.jingle.SmackLogger;
-import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
-import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
-import org.jivesoftware.smackx.jingle.media.PayloadType;
-import org.jivesoftware.smackx.jingle.mediaimpl.JMFInit;
-import org.jivesoftware.smackx.jingle.nat.JingleTransportManager;
-import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
-
-/**
- * Implements a jingleMediaManager using JMF based API and JSpeex.
- * It supports Speex codec.
- * <i>This API only currently works on windows.</i>
- *
- * @author Thiago Camargo
- */
-public class SpeexMediaManager extends JingleMediaManager {
-
-	private static final SmackLogger LOGGER = SmackLogger.getLogger(SpeexMediaManager.class);
-
-	public static final String MEDIA_NAME = "Speex";
-
-    private List<PayloadType> payloads = new ArrayList<PayloadType>();
-
-    public SpeexMediaManager(JingleTransportManager transportManager) {
-        super(transportManager);
-        setupPayloads();
-        setupJMF();
-    }
-
-    /**
-     * Returns a new jingleMediaSession
-     *
-     * @param payloadType payloadType
-     * @param remote      remote Candidate
-     * @param local       local Candidate
-     * @return JingleMediaSession
-     */
-    public JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) {
-        return new AudioMediaSession(payloadType, remote, local, null,null);
-    }
-
-    /**
-     * Setup API supported Payloads
-     */
-    private void setupPayloads() {
-        payloads.add(new PayloadType.Audio(15, "speex"));
-    }
-
-    /**
-     * Return all supported Payloads for this Manager
-     *
-     * @return The Payload List
-     */
-    public List<PayloadType> getPayloads() {
-        return payloads;
-    }
-
-    /**
-     * Runs JMFInit the first time the application is started so that capture
-     * devices are properly detected and initialized by JMF.
-     */
-    public static void setupJMF() {
-        // .jmf is the place where we store the jmf.properties file used
-        // by JMF. if the directory does not exist or it does not contain
-        // a jmf.properties file. or if the jmf.properties file has 0 length
-        // then this is the first time we're running and should continue to
-        // with JMFInit
-        String homeDir = System.getProperty("user.home");
-        File jmfDir = new File(homeDir, ".jmf");
-        String classpath = System.getProperty("java.class.path");
-        classpath += System.getProperty("path.separator")
-                + jmfDir.getAbsolutePath();
-        System.setProperty("java.class.path", classpath);
-
-        if (!jmfDir.exists())
-            jmfDir.mkdir();
-
-        File jmfProperties = new File(jmfDir, "jmf.properties");
-
-        if (!jmfProperties.exists()) {
-            try {
-                jmfProperties.createNewFile();
-            }
-            catch (IOException ex) {
-                LOGGER.debug("Failed to create jmf.properties");
-                ex.printStackTrace();
-            }
-        }
-
-        // if we're running on linux checkout that libjmutil.so is where it
-        // should be and put it there.
-        runLinuxPreInstall();
-
-        if (jmfProperties.length() == 0) {
-            new JMFInit(null, false);
-        }
-
-    }
-
-    private static void runLinuxPreInstall() {
-        // @TODO Implement Linux Pre-Install
-    }
-    
-    public String getName() {
-        return MEDIA_NAME;
-    }
-}
Index: org/jivesoftware/smackx/jingle/mediaimpl/jspeex/AudioMediaSession.java
===================================================================
--- org/jivesoftware/smackx/jingle/mediaimpl/jspeex/AudioMediaSession.java	(revision 11644)
+++ org/jivesoftware/smackx/jingle/mediaimpl/jspeex/AudioMediaSession.java	(working copy)
@@ -1,245 +0,0 @@
-/**
- * $RCSfile: AudioMediaSession.java,v $
- * $Revision: 1.1 $
- * $Date: 25/12/2006
- * <p/>
- * Copyright 2003-2006 Jive Software.
- * <p/>
- * All rights reserved. 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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.jivesoftware.smackx.jingle.mediaimpl.jspeex;
-
-import java.io.IOException;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.security.GeneralSecurityException;
-
-import javax.media.NoProcessorException;
-import javax.media.format.UnsupportedFormatException;
-import javax.media.rtp.rtcp.SenderReport;
-import javax.media.rtp.rtcp.SourceDescription;
-
-import mil.jfcom.cie.media.session.MediaSession;
-import mil.jfcom.cie.media.session.MediaSessionListener;
-import mil.jfcom.cie.media.session.StreamPlayer;
-import mil.jfcom.cie.media.srtp.packetizer.SpeexFormat;
-
-import org.jivesoftware.smackx.jingle.JingleSession;
-import org.jivesoftware.smackx.jingle.SmackLogger;
-import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
-import org.jivesoftware.smackx.jingle.media.PayloadType;
-import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
-
-/**
- * This Class implements a complete JingleMediaSession.
- * It sould be used to transmit and receive audio captured from the Mic.
- * This Class should be automaticly controlled by JingleSession.
- * But you could also use in any VOIP application.
- * For better NAT Traversal support this implementation don't support only receive or only transmit.
- * To receive you MUST transmit. So the only implemented and functionally methods are startTransmit() and stopTransmit()
- *
- * @author Thiago Camargo
- */
-
-public class AudioMediaSession extends JingleMediaSession implements MediaSessionListener {
-
-	private static final SmackLogger LOGGER = SmackLogger.getLogger(AudioMediaSession.class);
-
-	private MediaSession mediaSession;
-
-    /**
-     * Create a Session using Speex Codec
-     *
-     * @param localhost    localHost
-     * @param localPort    localPort
-     * @param remoteHost   remoteHost
-     * @param remotePort   remotePort
-     * @param eventHandler eventHandler
-     * @param quality      quality
-     * @param secure       secure
-     * @param micOn        micOn
-     * @return MediaSession
-     * @throws NoProcessorException
-     * @throws UnsupportedFormatException
-     * @throws IOException
-     * @throws GeneralSecurityException
-     */
-    public static MediaSession createSession(String localhost, int localPort, String remoteHost, int remotePort, MediaSessionListener eventHandler, int quality, boolean secure, boolean micOn) throws NoProcessorException, UnsupportedFormatException, IOException, GeneralSecurityException {
-
-        SpeexFormat.setFramesPerPacket(1);
-        /**
-         * The master key. Hardcoded for now.
-         */
-        byte[] masterKey = new byte[]{(byte) 0xE1, (byte) 0xF9, 0x7A, 0x0D, 0x3E, 0x01, (byte) 0x8B, (byte) 0xE0, (byte) 0xD6, 0x4F, (byte) 0xA3, 0x2C, 0x06, (byte) 0xDE, 0x41, 0x39};
-
-        /**
-         * The master salt. Hardcoded for now.
-         */
-        byte[] masterSalt = new byte[]{0x0E, (byte) 0xC6, 0x75, (byte) 0xAD, 0x49, (byte) 0x8A, (byte) 0xFE, (byte) 0xEB, (byte) 0xB6, (byte) 0x96, 0x0B, 0x3A, (byte) 0xAB, (byte) 0xE6};
-
-        DatagramSocket[] localPorts = MediaSession.getLocalPorts(InetAddress.getByName(localhost), localPort);
-        MediaSession session = MediaSession.createInstance(remoteHost, remotePort, localPorts, quality, secure, masterKey, masterSalt);
-        session.setListener(eventHandler);
-
-        session.setSourceDescription(new SourceDescription[]{new SourceDescription(SourceDescription.SOURCE_DESC_NAME, "Superman", 1, false), new SourceDescription(SourceDescription.SOURCE_DESC_EMAIL, "cdcie.tester@je.jfcom.mil", 1, false), new SourceDescription(SourceDescription.SOURCE_DESC_LOC, InetAddress.getByName(localhost) + " Port " + session.getLocalDataPort(), 1, false), new SourceDescription(SourceDescription.SOURCE_DESC_TOOL, "JFCOM CDCIE Audio Chat", 1, false)});
-        return session;
-    }
-
-
-    /**
-     * Creates a org.jivesoftware.jingleaudio.jspeex.AudioMediaSession with defined payload type, remote and local candidates
-     *
-     * @param payloadType Payload of the jmf
-     * @param remote      the remote information. The candidate that the jmf will be sent to.
-     * @param local       the local information. The candidate that will receive the jmf
-     * @param locator     media locator
-     */
-    public AudioMediaSession(final PayloadType payloadType, final TransportCandidate remote,
-            final TransportCandidate local, String locator, JingleSession jingleSession) {
-        super(payloadType, remote, local, locator == null ? "dsound://" : locator, jingleSession);
-        initialize();
-    }
-
-    /**
-     * Initialize the Audio Channel to make it able to send and receive audio
-     */
-    public void initialize() {
-
-        String ip;
-        String localIp;
-        int localPort;
-        int remotePort;
-
-        if (this.getLocal().getSymmetric() != null) {
-            ip = this.getLocal().getIp();
-            localIp = this.getLocal().getLocalIp();
-            localPort = getFreePort();
-            remotePort = this.getLocal().getSymmetric().getPort();
-
-            LOGGER.debug(this.getLocal().getConnection() + " " + ip + ": " + localPort + "->" + remotePort);
-
-        }
-        else {
-            ip = this.getRemote().getIp();
-            localIp = this.getLocal().getLocalIp();
-            localPort = this.getLocal().getPort();
-            remotePort = this.getRemote().getPort();
-        }
-
-        try {
-            mediaSession = createSession(localIp, localPort, ip, remotePort, this, 2, false, true);
-        }
-        catch (NoProcessorException e) {
-            e.printStackTrace();
-        }
-        catch (UnsupportedFormatException e) {
-            e.printStackTrace();
-        }
-        catch (IOException e) {
-            e.printStackTrace();
-        }
-        catch (GeneralSecurityException e) {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * Starts transmission and for NAT Traversal reasons start receiving also.
-     */
-    public void startTrasmit() {
-        try {
-            LOGGER.debug("start");
-            mediaSession.start(true);
-            this.mediaReceived("");
-        }
-        catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * Set transmit activity. If the active is true, the instance should trasmit.
-     * If it is set to false, the instance should pause transmit.
-     *
-     * @param active active state
-     */
-    public void setTrasmit(boolean active) {
-        // Do nothing
-    }
-
-    /**
-     * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
-     */
-    public void startReceive() {
-        // Do nothing
-    }
-
-    /**
-     * Stops transmission and for NAT Traversal reasons stop receiving also.
-     */
-    public void stopTrasmit() {
-        if (mediaSession != null)
-            mediaSession.close();
-    }
-
-    /**
-     * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
-     */
-    public void stopReceive() {
-        // Do nothing
-    }
-
-    public void newStreamIdentified(StreamPlayer streamPlayer) {
-    }
-
-    public void senderReportReceived(SenderReport report) {
-    }
-
-    public void streamClosed(StreamPlayer stream, boolean timeout) {
-    }
-
-    /**
-     * Obtain a free port we can use.
-     *
-     * @return A free port number.
-     */
-    protected int getFreePort() {
-        ServerSocket ss;
-        int freePort = 0;
-
-        for (int i = 0; i < 10; i++) {
-            freePort = (int) (10000 + Math.round(Math.random() * 10000));
-            freePort = freePort % 2 == 0 ? freePort : freePort + 1;
-            try {
-                ss = new ServerSocket(freePort);
-                freePort = ss.getLocalPort();
-                ss.close();
-                return freePort;
-            }
-            catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
-        try {
-            ss = new ServerSocket(0);
-            freePort = ss.getLocalPort();
-            ss.close();
-        }
-        catch (IOException e) {
-            e.printStackTrace();
-        }
-        return freePort;
-    }
-}
