Goals: Provide training in stratigraphy, sedimentology, paleontology, geochemistry and petrology of the Messinian geological record in the Sorbas Basin (Spain) with lectures, practical exercises, and fieldwork.
Tuesday April 23. Lectures: Origin of the Sorbas basin: structure and sedimentary infill (F. Sierro) – Marginal deposits: Messinian pre-and postevaporitic coral reefs and associated deposits (J. C. Braga) – Fieldwork: General Stratigraphy of the Sorbas Basin.
Wednesday April 24. Lecture: Abad Formation: Astronomical (Milankovitch) Climate Forcing (F. Hilgen) – Fieldwork: Field visit to the Sorbas basin: Pre-Messinian deposits.
Thursday April 25. Lectures: The Messinian Salinity Crisis: State of the Art (M.J. Herrero)- The Messinian Salinity Crisis impact on marine biota (K. Agiadi) – Fieldwork: Field visit to the Messinian Gypsum deposits.
Friday April 26. Lecture: The Coastal Marine Late Messinian Sorbas Member (C.J. Dabrio) – Fieldwork: Field visit to the Late Messinian Coastal deposits. Messinian post-evaporitic deposits.
Organizing Committee: María Josefa Herrero Fernández (University Complutense of Madrid), Konstantina Agiadi (University of Athens), Francisco Javier Sierro Sánchez (University of Salamanca), Juan Carlos Braga (University of Granada), Fritz Hilgen (Utrecht University).
Trainers: María Josefa Herrero Fernández (University Complutense of Madrid), Konstantina Agiadi (University of Athens), Francisco Javier Sierro Sánchez (University of Salamanca), Juan Carlos Braga (University of Granada), Fritz Hilgen (Utrecht University), Cristino Dabrio (University Complutense of Madrid), José Ignacio Escavy Fernández (University Politécnica of Madrid).
Participation: The school is co-organized with the Marie Skłodowska-Curie ETN SALTGIANT, which will provide up to 15 participants from the Early Stage researchers enrolled in the SALTGIANT PhD programs. MEDSALT will support the participation of up to 12 additional trainees with a fixed grant to cover the travel, accommodation, and subsistence costs.


I do understand the confusion, as for many years I was equally uninformed. I even needed to do some research to put together this post (it's difficult to keep detailed track of every way humans have discovered to exploit and abuse animals; sometimes I need a quick refresher course). So, for those of you who are trying to avoid harming animals but are unsure about wool, and for those of you just trying to understand what wool opponents could possibly have to complain about, this post is for you!
Now, I realize this isn't the most useful answer, which is why I get into the specifics below. However, if you've chosen to live your life without participating in a system of animal exploitation- that is, keeping animals captive and using their bodies or things that come out of their bodies for profit- wool is off limits. Whenever animals are viewed as commodities rather than sentient beings, corners will be cut- especially as demand rises. As I always say, animals are not fabric. Their skin, hair, fur, horns, etc. belong to them. Though this answer is the simplest, I realize it's not satisfactory for most inquiring minds, hence the following points.
The majority of the world's wool (approximately 80%) comes from Australia, where the majority of sheep producing it are known as merino sheep. These sheep were selectively bred centuries ago in Spain, so they are not native to Australia. Merino sheep were carefully designed by humans to have especially wrinkled skin. Wrinkled skin = more skin surface area = more wool = more money. Unfortunately, these wrinkles collect moisture as well as urine and feces (in the posterior region), which attracts flies. These flies lay eggs in the skin folds (a phenomenon known as "flystrike"), and when they hatch, maggots literally start eating the sheep alive. When untreated, this can cause a long, agonizing death. To prevent this horror, farmers use a pretty bizarre process referred to as "mulesing," in which they restrain the sheep upside down and literally slice off a giant chunk of their skin. This leaves behind a scarred, hairless surface that flies can't hide eggs in. Whenever my dog gets fleas, they tend to congregate below his tail, where it's dark and protected. I don't know why it's never occurred to me to just slice off that part of his body; problem solved! The most abhorrent part of mulesing is that painkillers/anesthesia are not required under Australian law.
REASON #3: Systematic Abuse, Mutilation, and Neglect.
As is common in many animal agriculture industries, babies (in this case, lambs) are castrated, have their tails docked, and have holes punched through their ears. This isn't unique to the wool industry, but that doesn't mean it's irrelevant. Shearing, though it conjures up images of a loving farmer sitting in a field, taking his sweet time to carefully trim his beloved sheep's hair, is often a very painful process. Most shearers aren't paid by the hour, but rather by the volume of wool they collect, so sheep are handled roughly and without regard for their comfort. Speed shearing is so revered that multiple shearing contests occur worldwide every year. Check out this video from such a contest in Australia. You won't see blood and injuries (the shearers know they're on camera), but you will see complete disregard for the sheep's comfort: http://vimeo.com/26055679. Additionally, because we've completely disregarded any semblance of a natural life for these animals, farmers sheer when they want to, not when preparing sheep for summer weather. An estimated one million sheep die every year from exposure within 30 days of shearing. Seems pretty unfair that we steal their wool to keep us warm and then leave them naked to freeze to death.
Arguably the worst part of the wool industry. Once sheep are "spent" (having produced an adequate amount of wool for one lifetime), millions are put onto jam packed ships and transported to the Middle East, where they are slaughtered in accordance with the laws (or lack thereof) of the country that receives them. For most sheep, this means they are killed by having their throats cut while still fully conscious. Sadly, those sheep are the lucky ones. Every year, tens of thousands die slow, painful deaths due to neglect and overcrowding on board the ships. Sheep that do survive the trip are typically exhausted and undernourished, and often have to be dragged onshore by their legs or ears. Numerous investigations have been carried out to reveal what happens next to these sheep, and you can find these (and a lot more info) at: http://www.banliveexport.com/investigations.
If you don't care about animal welfare, you might still be interested to know that wool production is unsurprisingly destructive to the environment in terms of land erosion, reduced biodiversity, and pollution. Patagonia, Argentina used to be second to Australia in terms of wool production, but it no longer holds this title due to the catastrophic consequences of raising massive quantities of sheep. One province in the vicinity has lost more than 50 million acres of land that was irreversibly damaged by sheep overgrazing. Additionally, wool treatment and processing requires massive amounts of chemicals; a common processing method known as "carbonization" involves bathing the material in hydrochloric acid. Mmm, cozy.
Thanks for your post, I think. I've never thought of the wool aspect. I've been vegan or vegitarian for 38 years because I love animals. Problem is I am also a fiber artist and have tons of wool. You made me think about this in a different way. My creative mind and ethical mind are going so fast I can't even describe the process. I may be time to think about working with recycled stuff.
Have you heard anything about the treatment of alpacas?
Thank you!! The effort you put into this shows!


text:
Home / Blog / National School Choice Week Is About Celebrating Uniqueness
National School Choice Week Is About Celebrating Uniqueness
Hispanic families understand the life-changing value of educational opportunity. And they know that every student in America deserves a quality education that fits his or her unique talents. Time and time again, polls have shown that Hispanics rank education as a top issue.
Hispanic families in particular understand that their children, have different learning styles, abilities and talents that are best met when they have access to a number of educational options. As evidence of this, Hispanics consistently show higher support for school choice policies compared to other demographic groups. Our diversity is what makes our country and our communities strong, and we deserve educational options capable of fully leveraging it.
Our individualism is something to be celebrated, especially in our children. But when it comes to their education, our children are often stuck in a one-size-fits-all system rather than one that focuses on what every individual child needs. The same educational setting and system that is effective for one child may not be effective for another.
Students and families should have access to a quality education that fits their needs and helps them succeed. To honor the qualities and characteristics that make our children who they are, our education policies should allow every family to choose the right school for their students, whether it's public, private, charter, homeschooling or a whole handful of other options.
When families have the freedom to choose the best education for their children, everyone wins. Just look at Florida.
The state made significant gains in performance and accessibility to programs tailored to each student's needs. In March, Gov. Rick Scott signed HB 7055 into law, which took huge steps toward more education freedom for all students. The bill:
Created the Hope Scholarship, allowing alternative education options for victims of bullying and harassment;
Established more accountability and transparency requirements for public unions, which allow educators to take control over their representation; and,
Made permanent the Principal Autonomy Pilot Program, which boosted the number of schools that benefit from increased administrative flexibility.
Florida's education reforms are just one example of how we can embrace our children's unique learning abilities and talents to set them up for the brightest possible future!
Support more educational freedom for families and students all over the country!
The LIBRE Initiative is a resource for the US Hispanic community with information and events to help you achieve prosperity!
Economic freedom is the key to prosperity; at LIBRE we want to empower Latinos to take charge of their future and finances!
You're the best person to decide how to manage your money. LIBRE wants to help you break free from government dependence!

redpajama_set_name: RedPajamaCommonCrawl


text:
package javax.sound.midi;

import java.io.FileInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import java.net.URL;

import javax.sound.midi.spi.MidiFileWriter;
import javax.sound.midi.spi.MidiFileReader;
import javax.sound.midi.spi.SoundbankReader;
import javax.sound.midi.spi.MidiDeviceProvider;

import com.sun.media.sound.JDK13Services;
import com.sun.media.sound.ReferenceCountingDevice;
import com.sun.media.sound.AutoConnectSequencer;
import com.sun.media.sound.MidiDeviceReceiverEnvelope;
import com.sun.media.sound.MidiDeviceTransmitterEnvelope;

/**
 * The MidiSystem class provides access to the installed MIDI
 * system resources, including devices such as synthesizers, sequencers, and
 * MIDI input and output ports.  A typical simple MIDI application might
 * begin by invoking one or more MidiSystem methods to learn
 * what devices are installed and to obtain the ones needed in that
 * application.
 *

 * The class also has methods for reading files, streams, and  URLs that
 * contain standard MIDI file data or soundbanks.  You can query the
 * MidiSystem for the format of a specified MIDI file.
 *

 * You cannot instantiate a MidiSystem; all the methods are
 * static.
 *
 *
Properties can be used to specify default MIDI devices.
 * Both system properties and a properties file are considered.
 * The properties file is "lib/sound.properties" in the JRE
 * directory. If a property exists both as a system property and in the
 * properties file, the system property takes precedence. If none is
 * specified, a suitable default is chosen among the available devices.
 * The syntax of the properties file is specified in
 * {@link java.util.Properties#load(InputStream) Properties.load}. The
 * following table lists the available property keys and which methods
 * consider them:
 *
 *

 *

 *   Property Key
 *   Interface
 *   Affected Method
 *

 *

 *   javax.sound.midi.Receiver
 *   {@link Receiver}
 *   {@link #getReceiver}
 *

 *

 *   javax.sound.midi.Sequencer
 *   {@link Sequencer}
 *   {@link #getSequencer}
 *

 *

 *   javax.sound.midi.Synthesizer
 *   {@link Synthesizer}
 *   {@link #getSynthesizer}
 *

 *

 *   javax.sound.midi.Transmitter
 *   {@link Transmitter}
 *   {@link #getTransmitter}
 *

 *

 *
 * The property value consists of the provider class name
 * and the device name, separated by the hash mark ("#").
 * The provider class name is the fully-qualified
 * name of a concrete {@link javax.sound.midi.spi.MidiDeviceProvider
 * MIDI device provider} class. The device name is matched against
 * the String returned by the getName
 * method of MidiDevice.Info.
 * Either the class name, or the device name may be omitted.
 * If only the class name is specified, the trailing hash mark
 * is optional.
 *
 *
If the provider class is specified, and it can be
 * successully retrieved from the installed providers,
 * the list of
 * MidiDevice.Info objects is retrieved
 * from the provider. Otherwise, or when these devices
 * do not provide a subsequent match, the list is retrieved
 * from {@link #getMidiDeviceInfo} to contain
 * all available MidiDevice.Info objects.
 *
 *
If a device name is specified, the resulting list of
 * MidiDevice.Info objects is searched:
 * the first one with a matching name, and whose
 * MidiDevice implements the
 * respective interface, will be returned.
 * If no matching MidiDevice.Info object
 * is found, or the device name is not specified,
 * the first suitable device from the resulting
 * list will be returned. For Sequencer and Synthesizer,
 * a device is suitable if it implements the respective
 * interface; whereas for Receiver and Transmitter, a device is
 * suitable if it
 * implements neither Sequencer nor Synthesizer and provides
 * at least one Receiver or Transmitter, respectively.
 *
 * For example, the property javax.sound.midi.Receiver
 * with a value
 * "com.sun.media.sound.MidiProvider#SunMIDI1"
 * will have the following consequences when
 * getReceiver is called:
 * if the class com.sun.media.sound.MidiProvider exists
 * in the list of installed MIDI device providers,
 * the first Receiver device with name
 * "SunMIDI1" will be returned. If it cannot
 * be found, the first Receiver from that provider
 * will be returned, regardless of name.
 * If there is none, the first Receiver with name
 * "SunMIDI1" in the list of all devices
 * (as returned by getMidiDeviceInfo) will be returned,
 * or, if not found, the first Receiver that can
 * be found in the list of all devices is returned.
 * If that fails, too, a MidiUnavailableException
 * is thrown.
 *
 * @author Kara Kytle
 * @author Florian Bomers
 * @author Matthias Pfisterer
 */
public class MidiSystem {

    /**
     * Private no-args constructor for ensuring against instantiation.
     */
    private MidiSystem() {
    }

    /**
     * Obtains an array of information objects representing
     * the set of all MIDI devices available on the system.
     * A returned information object can then be used to obtain the
     * corresponding device object, by invoking
     * {@link #getMidiDevice(MidiDevice.Info) getMidiDevice}.
     *
     * @return an array of MidiDevice.Info objects, one
     * for each installed MIDI device.  If no such devices are installed,
     * an array of length 0 is returned.
     */
    public static MidiDevice.Info[] getMidiDeviceInfo() {
        List allInfos = new ArrayList();
        List providers = getMidiDeviceProviders();

        for(int i = 0; i < providers.size(); i++) {
            MidiDeviceProvider provider = (MidiDeviceProvider) providers.get(i);
            MidiDevice.Info[] tmpinfo = provider.getDeviceInfo();
            for (int j = 0; j < tmpinfo.length; j++) {
                allInfos.add( tmpinfo[j] );
            }
        }
        MidiDevice.Info[] infosArray = (MidiDevice.Info[]) allInfos.toArray(new MidiDevice.Info[0]);
        return infosArray;
    }

    /**
     * Obtains the requested MIDI device.
     *
     * @param info a device information object representing the desired device.
     * @return the requested device
     * @throws MidiUnavailableException if the requested device is not available
     * due to resource restrictions
     * @throws IllegalArgumentException if the info object does not represent
     * a MIDI device installed on the system
     * @see #getMidiDeviceInfo
     */
    public static MidiDevice getMidiDevice(MidiDevice.Info info) throws MidiUnavailableException {
        List providers = getMidiDeviceProviders();

        for(int i = 0; i < providers.size(); i++) {
            MidiDeviceProvider provider = (MidiDeviceProvider) providers.get(i);
            if (provider.isDeviceSupported(info)) {
                MidiDevice device = provider.getDevice(info);
                return device;
            }
        }
        throw new IllegalArgumentException("Requested device not installed: " + info);
    }

    /**
     * Obtains a MIDI receiver from an external MIDI port
     * or other default device.
     * The returned receiver always implements
     * the {@code MidiDeviceReceiver} interface.
     *
     *
If the system property
     * javax.sound.midi.Receiver
     * is defined or it is defined in the file "sound.properties",
     * it is used to identify the device that provides the default receiver.
     * For details, refer to the {@link MidiSystem class description}.
     *
     * If a suitable MIDI port is not available, the Receiver is
     * retrieved from an installed synthesizer.
     *
     *
If a native receiver provided by the default device does not implement
     * the {@code MidiDeviceReceiver} interface, it will be wrapped in a
     * wrapper class that implements the {@code MidiDeviceReceiver} interface.
     * The corresponding {@code Receiver} method calls will be forwarded
     * to the native receiver.
     *
     *
If this method returns successfully, the {@link
     * javax.sound.midi.MidiDevice MidiDevice} the
     * Receiver belongs to is opened implicitly, if it is
     * not already open. It is possible to close an implicitly opened
     * device by calling {@link javax.sound.midi.Receiver#close close}
     * on the returned Receiver. All open Receiver
     * instances have to be closed in order to release system resources
     * hold by the MidiDevice. For a
     * detailed description of open/close behaviour see the class
     * description of {@link javax.sound.midi.MidiDevice MidiDevice}.
     *
     *
     * @return the default MIDI receiver
     * @throws MidiUnavailableException if the default receiver is not
     *         available due to resource restrictions,
     *         or no device providing receivers is installed in the system
     */
    public static Receiver getReceiver() throws MidiUnavailableException {
        // may throw MidiUnavailableException
        MidiDevice device = getDefaultDeviceWrapper(Receiver.class);
        Receiver receiver;
        if (device instanceof ReferenceCountingDevice) {
            receiver = ((ReferenceCountingDevice) device).getReceiverReferenceCounting();
        } else {
            receiver = device.getReceiver();
        }
        if (!(receiver instanceof MidiDeviceReceiver)) {
            receiver = new MidiDeviceReceiverEnvelope(device, receiver);
        }
        return receiver;
    }

    /**
     * Obtains a MIDI transmitter from an external MIDI port
     * or other default source.
     * The returned transmitter always implements
     * the {@code MidiDeviceTransmitter} interface.
     *
     *
If the system property
     * javax.sound.midi.Transmitter
     * is defined or it is defined in the file "sound.properties",
     * it is used to identify the device that provides the default transmitter.
     * For details, refer to the {@link MidiSystem class description}.
     *
     *
If a native transmitter provided by the default device does not implement
     * the {@code MidiDeviceTransmitter} interface, it will be wrapped in a
     * wrapper class that implements the {@code MidiDeviceTransmitter} interface.
     * The corresponding {@code Transmitter} method calls will be forwarded
     * to the native transmitter.
     *
     *
If this method returns successfully, the {@link
     * javax.sound.midi.MidiDevice MidiDevice} the
     * Transmitter belongs to is opened implicitly, if it
     * is not already open. It is possible to close an implicitly
     * opened device by calling {@link
     * javax.sound.midi.Transmitter#close close} on the returned
     * Transmitter. All open Transmitter
     * instances have to be closed in order to release system resources
     * hold by the MidiDevice. For a detailed description
     * of open/close behaviour see the class description of {@link
     * javax.sound.midi.MidiDevice MidiDevice}.
     *
     * @return the default MIDI transmitter
     * @throws MidiUnavailableException if the default transmitter is not
     *         available due to resource restrictions,
     *         or no device providing transmitters is installed in the system
     */
    public static Transmitter getTransmitter() throws MidiUnavailableException {
        // may throw MidiUnavailableException
        MidiDevice device = getDefaultDeviceWrapper(Transmitter.class);
        Transmitter transmitter;
        if (device instanceof ReferenceCountingDevice) {
            transmitter = ((ReferenceCountingDevice) device).getTransmitterReferenceCounting();
        } else {
            transmitter = device.getTransmitter();
        }
        if (!(transmitter instanceof MidiDeviceTransmitter)) {
            transmitter = new MidiDeviceTransmitterEnvelope(device, transmitter);
        }
        return transmitter;
    }

    /**
     * Obtains the default synthesizer.
     *
     *
If the system property
     * javax.sound.midi.Synthesizer
     * is defined or it is defined in the file "sound.properties",
     * it is used to identify the default synthesizer.
     * For details, refer to the {@link MidiSystem class description}.
     *
     * @return the default synthesizer
     * @throws MidiUnavailableException if the synthesizer is not
     *         available due to resource restrictions,
     *         or no synthesizer is installed in the system
     */
    public static Synthesizer getSynthesizer() throws MidiUnavailableException {
        // may throw MidiUnavailableException
        return (Synthesizer) getDefaultDeviceWrapper(Synthesizer.class);
    }

    /**
     * Obtains the default Sequencer, connected to
     * a default device.
     * The returned Sequencer instance is
     * connected to the default Synthesizer,
     * as returned by {@link #getSynthesizer}.
     * If there is no Synthesizer
     * available, or the default Synthesizer
     * cannot be opened, the sequencer is connected
     * to the default Receiver, as returned
     * by {@link #getReceiver}.
     * The connection is made by retrieving a Transmitter
     * instance from the Sequencer and setting its
     * Receiver.
     * Closing and re-opening the sequencer will restore the
     * connection to the default device.
     *
     *
This method is equivalent to calling
     * getSequencer(true).
     *
     *
If the system property
     * javax.sound.midi.Sequencer
     * is defined or it is defined in the file "sound.properties",
     * it is used to identify the default sequencer.
     * For details, refer to the {@link MidiSystem class description}.
     *
     * @return the default sequencer, connected to a default Receiver
     * @throws MidiUnavailableException if the sequencer is not
     *         available due to resource restrictions,
     *         or there is no Receiver available by any
     *         installed MidiDevice,
     *         or no sequencer is installed in the system.
     * @see #getSequencer(boolean)
     * @see #getSynthesizer
     * @see #getReceiver
     */
    public static Sequencer getSequencer() throws MidiUnavailableException {
        return getSequencer(true);
    }

    /**
     * Obtains the default Sequencer, optionally
     * connected to a default device.
     *
     *
If connected is true, the returned
     * Sequencer instance is
     * connected to the default Synthesizer,
     * as returned by {@link #getSynthesizer}.
     * If there is no Synthesizer
     * available, or the default Synthesizer
     * cannot be opened, the sequencer is connected
     * to the default Receiver, as returned
     * by {@link #getReceiver}.
     * The connection is made by retrieving a Transmitter
     * instance from the Sequencer and setting its
     * Receiver.
     * Closing and re-opening the sequencer will restore the
     * connection to the default device.
     *
     *
If connected is false, the returned
     * Sequencer instance is not connected, it
     * has no open Transmitters. In order to
     * play the sequencer on a MIDI device, or a Synthesizer,
     * it is necessary to get a Transmitter and set its
     * Receiver.
     *
     *
If the system property
     * javax.sound.midi.Sequencer
     * is defined or it is defined in the file "sound.properties",
     * it is used to identify the default sequencer.
     * For details, refer to the {@link MidiSystem class description}.
     *
     * @return the default sequencer
     * @throws MidiUnavailableException if the sequencer is not
     *         available due to resource restrictions,
     *         or no sequencer is installed in the system,
     *         or if connected is true, and there is
     *         no Receiver available by any installed
     *         MidiDevice
     * @see #getSynthesizer
     * @see #getReceiver
     * @since 1.5
     */
    public static Sequencer getSequencer(boolean connected)
        throws MidiUnavailableException {
        Sequencer seq = (Sequencer) getDefaultDeviceWrapper(Sequencer.class);

        if (connected) {
            // IMPORTANT: this code needs to be synch'ed with
            //            all AutoConnectSequencer instances,
            //            (e.g. RealTimeSequencer) because the
            //            same algorithm for synth retrieval
            //            needs to be used!

            Receiver rec = null;
            MidiUnavailableException mue = null;

            // first try to connect to the default synthesizer
            try {
                Synthesizer synth = getSynthesizer();
                if (synth instanceof ReferenceCountingDevice) {
                    rec = ((ReferenceCountingDevice) synth).getReceiverReferenceCounting();
                } else {
                    synth.open();
                    try {
                        rec = synth.getReceiver();
                    } finally {
                        // make sure that the synth is properly closed
                        if (rec == null) {
                            synth.close();
                        }
                    }
                }
            } catch (MidiUnavailableException e) {
                // something went wrong with synth
                if (e instanceof MidiUnavailableException) {
                    mue = (MidiUnavailableException) e;
                }
            }
            if (rec == null) {
                // then try to connect to the default Receiver
                try {
                    rec = MidiSystem.getReceiver();
                } catch (Exception e) {
                    // something went wrong. Nothing to do then!
                    if (e instanceof MidiUnavailableException) {
                        mue = (MidiUnavailableException) e;
                    }
                }
            }
            if (rec != null) {
                seq.getTransmitter().setReceiver(rec);
                if (seq instanceof AutoConnectSequencer) {
                    ((AutoConnectSequencer) seq).setAutoConnect(rec);
                }
            } else {
                if (mue != null) {
                    throw mue;
                }
                throw new MidiUnavailableException("no receiver available");
            }
        }
        return seq;
    }

    /**
     * Constructs a MIDI sound bank by reading it from the specified stream.
     * The stream must point to
     * a valid MIDI soundbank file.  In general, MIDI soundbank providers may
     * need to read some data from the stream before determining whether they
     * support it.  These parsers must
     * be able to mark the stream, read enough data to determine whether they
     * support the stream, and, if not, reset the stream's read pointer to
     * its original position.  If the input stream does not support this,
     * this method may fail with an IOException.
     * @param stream the source of the sound bank data.
     * @return the sound bank
     * @throws InvalidMidiDataException if the stream does not point to
     * valid MIDI soundbank data recognized by the system
     * @throws IOException if an I/O error occurred when loading the soundbank
     * @see InputStream#markSupported
     * @see InputStream#mark
     */
    public static Soundbank getSoundbank(InputStream stream)
        throws InvalidMidiDataException, IOException {

        SoundbankReader sp = null;
        Soundbank s = null;

        List providers = getSoundbankReaders();

        for(int i = 0; i < providers.size(); i++) {
            sp = (SoundbankReader)providers.get(i);
            s = sp.getSoundbank(stream);

            if( s!= null) {
                return s;
            }
        }
        throw new InvalidMidiDataException("cannot get soundbank from stream");

    }

    /**
     * Constructs a Soundbank by reading it from the specified URL.
     * The URL must point to a valid MIDI soundbank file.
     *
     * @param url the source of the sound bank data
     * @return the sound bank
     * @throws InvalidMidiDataException if the URL does not point to valid MIDI
     * soundbank data recognized by the system
     * @throws IOException if an I/O error occurred when loading the soundbank
     */
    public static Soundbank getSoundbank(URL url)
        throws InvalidMidiDataException, IOException {

        SoundbankReader sp = null;
        Soundbank s = null;

        List providers = getSoundbankReaders();

        for(int i = 0; i < providers.size(); i++) {
            sp = (SoundbankReader)providers.get(i);
            s = sp.getSoundbank(url);

            if( s!= null) {
                return s;
            }
        }
        throw new InvalidMidiDataException("cannot get soundbank from stream");

    }

    /**
     * Constructs a Soundbank by reading it from the specified
     * File.
     * The File must point to a valid MIDI soundbank file.
     *
     * @param file the source of the sound bank data
     * @return the sound bank
     * @throws InvalidMidiDataException if the File does not
     * point to valid MIDI soundbank data recognized by the system
     * @throws IOException if an I/O error occurred when loading the soundbank
     */
    public static Soundbank getSoundbank(File file)
        throws InvalidMidiDataException, IOException {

        SoundbankReader sp = null;
        Soundbank s = null;

        List providers = getSoundbankReaders();

        for(int i = 0; i < providers.size(); i++) {
            sp = (SoundbankReader)providers.get(i);
            s = sp.getSoundbank(file);

            if( s!= null) {
                return s;
            }
        }
        throw new InvalidMidiDataException("cannot get soundbank from stream");
    }

    /**
     * Obtains the MIDI file format of the data in the specified input stream.
     * The stream must point to valid MIDI file data for a file type recognized
     * by the system.
     *

     * This method and/or the code it invokes may need to read some data from
     * the stream to determine whether its data format is supported.  The
     * implementation may therefore
     * need to mark the stream, read enough data to determine whether it is in
     * a supported format, and reset the stream's read pointer to its original
     * position.  If the input stream does not permit this set of operations,
     * this method may fail with an IOException.
     *

     * This operation can only succeed for files of a type which can be parsed
     * by an installed file reader.  It may fail with an InvalidMidiDataException
     * even for valid files if no compatible file reader is installed.  It
     * will also fail with an InvalidMidiDataException if a compatible file reader
     * is installed, but encounters errors while determining the file format.
     *
     * @param stream the input stream from which file format information
     * should be extracted
     * @return an MidiFileFormat object describing the MIDI file
     * format
     * @throws InvalidMidiDataException if the stream does not point to valid
     * MIDI file data recognized by the system
     * @throws IOException if an I/O exception occurs while accessing the
     * stream
     * @see #getMidiFileFormat(URL)
     * @see #getMidiFileFormat(File)
     * @see InputStream#markSupported
     * @see InputStream#mark
     */
    public static MidiFileFormat getMidiFileFormat(InputStream stream)
        throws InvalidMidiDataException, IOException {

        List providers = getMidiFileReaders();
        MidiFileFormat format = null;

        for(int i = 0; i < providers.size(); i++) {
            MidiFileReader reader = (MidiFileReader) providers.get(i);
            try {
                format = reader.getMidiFileFormat( stream ); // throws IOException
                break;
            } catch (InvalidMidiDataException e) {
                continue;
            }
        }

        if( format==null ) {
            throw new InvalidMidiDataException("input stream is not a supported file type");
        } else {
            return format;
        }
    }

    /**
     * Obtains the MIDI file format of the data in the specified URL.  The URL
     * must point to valid MIDI file data for a file type recognized
     * by the system.
     *

     * This operation can only succeed for files of a type which can be parsed
     * by an installed file reader.  It may fail with an InvalidMidiDataException
     * even for valid files if no compatible file reader is installed.  It
     * will also fail with an InvalidMidiDataException if a compatible file reader
     * is installed, but encounters errors while determining the file format.
     *
     * @param url the URL from which file format information should be
     * extracted
     * @return a MidiFileFormat object describing the MIDI file
     * format
     * @throws InvalidMidiDataException if the URL does not point to valid MIDI
     * file data recognized by the system
     * @throws IOException if an I/O exception occurs while accessing the URL
     *
     * @see #getMidiFileFormat(InputStream)
     * @see #getMidiFileFormat(File)
     */
    public static MidiFileFormat getMidiFileFormat(URL url)
        throws InvalidMidiDataException, IOException {

        List providers = getMidiFileReaders();
        MidiFileFormat format = null;

        for(int i = 0; i < providers.size(); i++) {
            MidiFileReader reader = (MidiFileReader) providers.get(i);
            try {
                format = reader.getMidiFileFormat( url ); // throws IOException
                break;
            } catch (InvalidMidiDataException e) {
                continue;
            }
        }

        if( format==null ) {
            throw new InvalidMidiDataException("url is not a supported file type");
        } else {
            return format;
        }
    }

    /**
     * Obtains the MIDI file format of the specified File.  The
     * File must point to valid MIDI file data for a file type
     * recognized by the system.
     *

     * This operation can only succeed for files of a type which can be parsed
     * by an installed file reader.  It may fail with an InvalidMidiDataException
     * even for valid files if no compatible file reader is installed.  It
     * will also fail with an InvalidMidiDataException if a compatible file reader
     * is installed, but encounters errors while determining the file format.
     *
     * @param file the File from which file format information
     * should be extracted
     * @return a MidiFileFormat object describing the MIDI file
     * format
     * @throws InvalidMidiDataException if the File does not point
     *  to valid MIDI file data recognized by the system
     * @throws IOException if an I/O exception occurs while accessing the file
     *
     * @see #getMidiFileFormat(InputStream)
     * @see #getMidiFileFormat(URL)
     */
    public static MidiFileFormat getMidiFileFormat(File file)
        throws InvalidMidiDataException, IOException {

        List providers = getMidiFileReaders();
        MidiFileFormat format = null;

        for(int i = 0; i < providers.size(); i++) {
            MidiFileReader reader = (MidiFileReader) providers.get(i);
            try {
                format = reader.getMidiFileFormat( file ); // throws IOException
                break;
            } catch (InvalidMidiDataException e) {
                continue;
            }
        }

        if( format==null ) {
            throw new InvalidMidiDataException("file is not a supported file type");
        } else {
            return format;
        }
    }

    /**
     * Obtains a MIDI sequence from the specified input stream.  The stream must
     * point to valid MIDI file data for a file type recognized
     * by the system.
     *

     * This method and/or the code it invokes may need to read some data
     * from the stream to determine whether
     * its data format is supported.  The implementation may therefore
     * need to mark the stream, read enough data to determine whether it is in
     * a supported format, and reset the stream's read pointer to its original
     * position.  If the input stream does not permit this set of operations,
     * this method may fail with an IOException.
     *

     * This operation can only succeed for files of a type which can be parsed
     * by an installed file reader.  It may fail with an InvalidMidiDataException
     * even for valid files if no compatible file reader is installed.  It
     * will also fail with an InvalidMidiDataException if a compatible file reader
     * is installed, but encounters errors while constructing the Sequence
     * object from the file data.
     *
     * @param stream the input stream from which the Sequence
     * should be constructed
     * @return a Sequence object based on the MIDI file data
     * contained in the input stream
     * @throws InvalidMidiDataException if the stream does not point to
     * valid MIDI file data recognized by the system
     * @throws IOException if an I/O exception occurs while accessing the
     * stream
     * @see InputStream#markSupported
     * @see InputStream#mark
     */
    public static Sequence getSequence(InputStream stream)
        throws InvalidMidiDataException, IOException {

        List providers = getMidiFileReaders();
        Sequence sequence = null;

        for(int i = 0; i < providers.size(); i++) {
            MidiFileReader reader = (MidiFileReader) providers.get(i);
            try {
                sequence = reader.getSequence( stream ); // throws IOException
                break;
            } catch (InvalidMidiDataException e) {
                continue;
            }
        }

        if( sequence==null ) {
            throw new InvalidMidiDataException("could not get sequence from input stream");
        } else {
            return sequence;
        }
    }

    /**
     * Obtains a MIDI sequence from the specified URL.  The URL must
     * point to valid MIDI file data for a file type recognized
     * by the system.
     *

     * This operation can only succeed for files of a type which can be parsed
     * by an installed file reader.  It may fail with an InvalidMidiDataException
     * even for valid files if no compatible file reader is installed.  It
     * will also fail with an InvalidMidiDataException if a compatible file reader
     * is installed, but encounters errors while constructing the Sequence
     * object from the file data.
     *
     * @param url the URL from which the Sequence should be
     * constructed
     * @return a Sequence object based on the MIDI file data
     * pointed to by the URL
     * @throws InvalidMidiDataException if the URL does not point to valid MIDI
     * file data recognized by the system
     * @throws IOException if an I/O exception occurs while accessing the URL
     */
    public static Sequence getSequence(URL url)
        throws InvalidMidiDataException, IOException {

        List providers = getMidiFileReaders();
        Sequence sequence = null;

        for(int i = 0; i < providers.size(); i++) {
            MidiFileReader reader = (MidiFileReader) providers.get(i);
            try {
                sequence = reader.getSequence( url ); // throws IOException
                break;
            } catch (InvalidMidiDataException e) {
                continue;
            }
        }

        if( sequence==null ) {
            throw new InvalidMidiDataException("could not get sequence from URL");
        } else {
            return sequence;
        }
    }

    /**
     * Obtains a MIDI sequence from the specified File.
     * The File must point to valid MIDI file data
     * for a file type recognized by the system.
     *

     * This operation can only succeed for files of a type which can be parsed
     * by an installed file reader.  It may fail with an InvalidMidiDataException
     * even for valid files if no compatible file reader is installed.  It
     * will also fail with an InvalidMidiDataException if a compatible file reader
     * is installed, but encounters errors while constructing the Sequence
     * object from the file data.
     *
     * @param file the File from which the Sequence
     * should be constructed
     * @return a Sequence object based on the MIDI file data
     * pointed to by the File
     * @throws InvalidMidiDataException if the File does not point to valid MIDI
     * file data recognized by the system
     * @throws IOException if an I/O exception occurs
     */
    public static Sequence getSequence(File file)
        throws InvalidMidiDataException, IOException {

        List providers = getMidiFileReaders();
        Sequence sequence = null;

        for(int i = 0; i < providers.size(); i++) {
            MidiFileReader reader = (MidiFileReader) providers.get(i);
            try {
                sequence = reader.getSequence( file ); // throws IOException
                break;
            } catch (InvalidMidiDataException e) {
                continue;
            }
        }

        if( sequence==null ) {
            throw new InvalidMidiDataException("could not get sequence from file");
        } else {
            return sequence;
        }
    }

    /**
     * Obtains the set of MIDI file types for which file writing support is
     * provided by the system.
     * @return array of unique file types.  If no file types are supported,
     * an array of length 0 is returned.
     */
    public static int[] getMidiFileTypes() {

        List providers = getMidiFileWriters();
        Set allTypes = new HashSet();

        // gather from all the providers

        for (int i = 0; i < providers.size(); i++ ) {
            MidiFileWriter writer = (MidiFileWriter) providers.get(i);
            int[] types = writer.getMidiFileTypes();
            for (int j = 0; j < types.length; j++ ) {
                allTypes.add(new Integer(types[j]));
            }
        }
        int resultTypes[] = new int[allTypes.size()];
        int index = 0;
        Iterator iterator = allTypes.iterator();
        while (iterator.hasNext()) {
            Integer integer = (Integer) iterator.next();
            resultTypes[index++] = integer.intValue();
        }
        return resultTypes;
    }

    /**
     * Indicates whether file writing support for the specified MIDI file type
     * is provided by the system.
     * @param fileType the file type for which write capabilities are queried
     * @return true if the file type is supported,
     * otherwise false
     */
    public static boolean isFileTypeSupported(int fileType) {

        List providers = getMidiFileWriters();

        for (int i = 0; i < providers.size(); i++ ) {
            MidiFileWriter writer = (MidiFileWriter) providers.get(i);
            if( writer.isFileTypeSupported(fileType)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Obtains the set of MIDI file types that the system can write from the
     * sequence specified.
     * @param sequence the sequence for which MIDI file type support
     * is queried
     * @return the set of unique supported file types.  If no file types are supported,
     * returns an array of length 0.
     */
    public static int[] getMidiFileTypes(Sequence sequence) {

        List providers = getMidiFileWriters();
        Set allTypes = new HashSet();

        // gather from all the providers

        for (int i = 0; i < providers.size(); i++ ) {
            MidiFileWriter writer = (MidiFileWriter) providers.get(i);
            int[] types = writer.getMidiFileTypes(sequence);
            for (int j = 0; j < types.length; j++ ) {
                allTypes.add(new Integer(types[j]));
            }
        }
        int resultTypes[] = new int[allTypes.size()];
        int index = 0;
        Iterator iterator = allTypes.iterator();
        while (iterator.hasNext()) {
            Integer integer = (Integer) iterator.next();
            resultTypes[index++] = integer.intValue();
        }
        return resultTypes;
    }

    /**
     * Indicates whether a MIDI file of the file type specified can be written
     * from the sequence indicated.
     * @param fileType the file type for which write capabilities
     * are queried
     * @param sequence the sequence for which file writing support is queried
     * @return true if the file type is supported for this
     * sequence, otherwise false
     */
    public static boolean isFileTypeSupported(int fileType, Sequence sequence) {

        List providers = getMidiFileWriters();

        for (int i = 0; i < providers.size(); i++ ) {
            MidiFileWriter writer = (MidiFileWriter) providers.get(i);
            if( writer.isFileTypeSupported(fileType,sequence)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Writes a stream of bytes representing a file of the MIDI file type
     * indicated to the output stream provided.
     * @param in sequence containing MIDI data to be written to the file
     * @param fileType the file type of the file to be written to the output stream
     * @param out stream to which the file data should be written
     * @return the number of bytes written to the output stream
     * @throws IOException if an I/O exception occurs
     * @throws IllegalArgumentException if the file format is not supported by
     * the system
     * @see #isFileTypeSupported(int, Sequence)
     * @see     #getMidiFileTypes(Sequence)
     */
    public static int write(Sequence in, int fileType, OutputStream out) throws IOException {

        List providers = getMidiFileWriters();
        //$$fb 2002-04-17: Fix for 4635287: Standard MidiFileWriter cannot write empty Sequences
        int bytesWritten = -2;

        for (int i = 0; i < providers.size(); i++ ) {
            MidiFileWriter writer = (MidiFileWriter) providers.get(i);
            if( writer.isFileTypeSupported( fileType, in ) ) {

                bytesWritten = writer.write(in, fileType, out);
                break;
            }
        }
        if (bytesWritten == -2) {
            throw new IllegalArgumentException("MIDI file type is not supported");
        }
        return bytesWritten;
    }

    /**
     * Writes a stream of bytes representing a file of the MIDI file type
     * indicated to the external file provided.
     * @param in sequence containing MIDI data to be written to the file
     * @param type the file type of the file to be written to the output stream
     * @param out external file to which the file data should be written
     * @return the number of bytes written to the file
     * @throws IOException if an I/O exception occurs
     * @throws IllegalArgumentException if the file type is not supported by
     * the system
     * @see #isFileTypeSupported(int, Sequence)
     * @see     #getMidiFileTypes(Sequence)
     */
    public static int write(Sequence in, int type, File out) throws IOException {

        List providers = getMidiFileWriters();
        //$$fb 2002-04-17: Fix for 4635287: Standard MidiFileWriter cannot write empty Sequences
        int bytesWritten = -2;

        for (int i = 0; i < providers.size(); i++ ) {
            MidiFileWriter writer = (MidiFileWriter) providers.get(i);
            if( writer.isFileTypeSupported( type, in ) ) {

                bytesWritten = writer.write(in, type, out);
                break;
            }
        }
        if (bytesWritten == -2) {
            throw new IllegalArgumentException("MIDI file type is not supported");
        }
        return bytesWritten;
    }

    // HELPER METHODS

    private static List getMidiDeviceProviders() {
        return getProviders(MidiDeviceProvider.class);
    }

    private static List getSoundbankReaders() {
        return getProviders(SoundbankReader.class);
    }

    private static List getMidiFileWriters() {
        return getProviders(MidiFileWriter.class);
    }

    private static List getMidiFileReaders() {
        return getProviders(MidiFileReader.class);
    }

    /** Attempts to locate and return a default MidiDevice of the specified
     * type.
     *
     * This method wraps {@link #getDefaultDevice}. It catches the
     * IllegalArgumentException thrown by
     * getDefaultDevice and instead throws a
     * MidiUnavailableException, with the catched
     * exception chained.
     *
     * @param deviceClass The requested device type, one of Synthesizer.class,
     * Sequencer.class, Receiver.class or Transmitter.class.
     * @throws  MidiUnavalableException on failure.
     */
    private static MidiDevice getDefaultDeviceWrapper(Class deviceClass)
        throws MidiUnavailableException{
        try {
            return getDefaultDevice(deviceClass);
        } catch (IllegalArgumentException iae) {
            MidiUnavailableException mae = new MidiUnavailableException();
            mae.initCause(iae);
            throw mae;
        }
    }

    /** Attempts to locate and return a default MidiDevice of the specified
     * type.
     *
     * @param deviceClass The requested device type, one of Synthesizer.class,
     * Sequencer.class, Receiver.class or Transmitter.class.
     * @throws  IllegalArgumentException on failure.
     */
    private static MidiDevice getDefaultDevice(Class deviceClass) {
        List providers = getMidiDeviceProviders();
        String providerClassName = JDK13Services.getDefaultProviderClassName(deviceClass);
        String instanceName = JDK13Services.getDefaultInstanceName(deviceClass);
        MidiDevice device;

        if (providerClassName != null) {
            MidiDeviceProvider defaultProvider = getNamedProvider(providerClassName, providers);
            if (defaultProvider != null) {
                if (instanceName != null) {
                    device = getNamedDevice(instanceName, defaultProvider, deviceClass);
                    if (device != null) {
                        return device;
                    }
                }
                device = getFirstDevice(defaultProvider, deviceClass);
                if (device != null) {
                    return device;
                }
            }
        }

        /* Provider class not specified or cannot be found, or
           provider class specified, and no appropriate device available or
           provider class and instance specified and instance cannot be found or is not appropriate */
        if (instanceName != null) {
            device = getNamedDevice(instanceName, providers, deviceClass);
            if (device != null) {
                return device;
            }
        }

        /* No default are specified, or if something is specified, everything
           failed. */
        device = getFirstDevice(providers, deviceClass);
        if (device != null) {
            return device;
        }
        throw new IllegalArgumentException("Requested device not installed");
    }

    /** Return a MidiDeviceProcider of a given class from the list of
        MidiDeviceProviders.

        @param providerClassName The class name of the provider to be returned.
        @param provider The list of MidiDeviceProviders that is searched.
        @return A MidiDeviceProvider of the requested class, or null if none
        is found.
    */
    private static MidiDeviceProvider getNamedProvider(String providerClassName, List providers) {
        for(int i = 0; i < providers.size(); i++) {
            MidiDeviceProvider provider = (MidiDeviceProvider) providers.get(i);
            if (provider.getClass().getName().equals(providerClassName)) {
                return provider;
            }
        }
        return null;
    }

    /** Return a MidiDevice with a given name from a given MidiDeviceProvider.
        @param deviceName The name of the MidiDevice to be returned.
        @param provider The MidiDeviceProvider to check for MidiDevices.
        @param deviceClass The requested device type, one of Synthesizer.class,
        Sequencer.class, Receiver.class or Transmitter.class.

        @return A MidiDevice matching the requirements, or null if none is found.
    */
    private static MidiDevice getNamedDevice(String deviceName,
                                             MidiDeviceProvider provider,
                                             Class deviceClass) {
        MidiDevice device;
        // try to get MIDI port
        device = getNamedDevice(deviceName, provider, deviceClass,
                                 false, false);
        if (device != null) {
            return device;
        }

        if (deviceClass == Receiver.class) {
            // try to get Synthesizer
            device = getNamedDevice(deviceName, provider, deviceClass,
                                     true, false);
            if (device != null) {
                return device;
            }
        }

        return null;
    }

    /** Return a MidiDevice with a given name from a given MidiDeviceProvider.
      @param deviceName The name of the MidiDevice to be returned.
      @param provider The MidiDeviceProvider to check for MidiDevices.
      @param deviceClass The requested device type, one of Synthesizer.class,
      Sequencer.class, Receiver.class or Transmitter.class.

      @return A MidiDevice matching the requirements, or null if none is found.
     */
    private static MidiDevice getNamedDevice(String deviceName,
                                             MidiDeviceProvider provider,
                                             Class deviceClass,
                                             boolean allowSynthesizer,
                                             boolean allowSequencer) {
        MidiDevice.Info[] infos = provider.getDeviceInfo();
        for (int i = 0; i < infos.length; i++) {
            if (infos[i].getName().equals(deviceName)) {
                MidiDevice device = provider.getDevice(infos[i]);
                if (isAppropriateDevice(device, deviceClass,
                                        allowSynthesizer, allowSequencer)) {
                    return device;
                }
            }
        }
        return null;
    }

    /** Return a MidiDevice with a given name from a list of
        MidiDeviceProviders.
        @param deviceName The name of the MidiDevice to be returned.
        @param providers The List of MidiDeviceProviders to check for
        MidiDevices.
        @param deviceClass The requested device type, one of Synthesizer.class,
        Sequencer.class, Receiver.class or Transmitter.class.
        @return A Mixer matching the requirements, or null if none is found.
    */
    private static MidiDevice getNamedDevice(String deviceName,
                                             List providers,
                                             Class deviceClass) {
        MidiDevice device;
        // try to get MIDI port
        device = getNamedDevice(deviceName, providers, deviceClass,
                                 false, false);
        if (device != null) {
            return device;
        }

        if (deviceClass == Receiver.class) {
            // try to get Synthesizer
            device = getNamedDevice(deviceName, providers, deviceClass,
                                     true, false);
            if (device != null) {
                return device;
            }
        }

        return null;
    }

    /** Return a MidiDevice with a given name from a list of
        MidiDeviceProviders.
        @param deviceName The name of the MidiDevice to be returned.
        @param providers The List of MidiDeviceProviders to check for
        MidiDevices.
        @param deviceClass The requested device type, one of Synthesizer.class,
        Sequencer.class, Receiver.class or Transmitter.class.
        @return A Mixer matching the requirements, or null if none is found.
     */
    private static MidiDevice getNamedDevice(String deviceName,
                                             List providers,
                                             Class deviceClass,
                                             boolean allowSynthesizer,
                                             boolean allowSequencer) {
        for(int i = 0; i < providers.size(); i++) {
            MidiDeviceProvider provider = (MidiDeviceProvider) providers.get(i);
            MidiDevice device = getNamedDevice(deviceName, provider,
                                               deviceClass,
                                               allowSynthesizer,
                                               allowSequencer);
            if (device != null) {
                return device;
            }
        }
        return null;
    }

    /** From a given MidiDeviceProvider, return the first appropriate device.
        @param provider The MidiDeviceProvider to check for MidiDevices.
        @param deviceClass The requested device type, one of Synthesizer.class,
        Sequencer.class, Receiver.class or Transmitter.class.
        @return A MidiDevice is considered appropriate, or null if no
        appropriate device is found.
    */
    private static MidiDevice getFirstDevice(MidiDeviceProvider provider,
                                             Class deviceClass) {
        MidiDevice device;
        // try to get MIDI port
        device = getFirstDevice(provider, deviceClass,
                                false, false);
        if (device != null) {
            return device;
        }

        if (deviceClass == Receiver.class) {
            // try to get Synthesizer
            device = getFirstDevice(provider, deviceClass,
                                    true, false);
            if (device != null) {
                return device;
            }
        }

        return null;
    }

    /** From a given MidiDeviceProvider, return the first appropriate device.
        @param provider The MidiDeviceProvider to check for MidiDevices.
        @param deviceClass The requested device type, one of Synthesizer.class,
        Sequencer.class, Receiver.class or Transmitter.class.
        @return A MidiDevice is considered appropriate, or null if no
        appropriate device is found.
     */
    private static MidiDevice getFirstDevice(MidiDeviceProvider provider,
                                             Class deviceClass,
                                             boolean allowSynthesizer,
                                             boolean allowSequencer) {
        MidiDevice.Info[] infos = provider.getDeviceInfo();
        for (int j = 0; j < infos.length; j++) {
            MidiDevice device = provider.getDevice(infos[j]);
            if (isAppropriateDevice(device, deviceClass,
                                    allowSynthesizer, allowSequencer)) {
                return device;
            }
        }
        return null;
    }

    /** From a List of MidiDeviceProviders, return the first appropriate
        MidiDevice.
        @param providers The List of MidiDeviceProviders to search.
        @param deviceClass The requested device type, one of Synthesizer.class,
        Sequencer.class, Receiver.class or Transmitter.class.
        @return A MidiDevice that is considered appropriate, or null
        if none is found.
    */
    private static MidiDevice getFirstDevice(List providers,
                                             Class deviceClass) {
        MidiDevice device;
        // try to get MIDI port
        device = getFirstDevice(providers, deviceClass,
                                false, false);
        if (device != null) {
            return device;
        }

        if (deviceClass == Receiver.class) {
            // try to get Synthesizer
            device = getFirstDevice(providers, deviceClass,
                                    true, false);
            if (device != null) {
                return device;
            }
        }

        return null;
    }

    /** From a List of MidiDeviceProviders, return the first appropriate
        MidiDevice.
        @param providers The List of MidiDeviceProviders to search.
        @param deviceClass The requested device type, one of Synthesizer.class,
        Sequencer.class, Receiver.class or Transmitter.class.
        @return A MidiDevice that is considered appropriate, or null
        if none is found.
     */
    private static MidiDevice getFirstDevice(List providers,
                                             Class deviceClass,
                                             boolean allowSynthesizer,
                                             boolean allowSequencer) {
        for(int i = 0; i < providers.size(); i++) {
            MidiDeviceProvider provider = (MidiDeviceProvider) providers.get(i);
            MidiDevice device = getFirstDevice(provider, deviceClass,
                                               allowSynthesizer,
                                               allowSequencer);
            if (device != null) {
                return device;
            }
        }
        return null;
    }

    /** Checks if a MidiDevice is appropriate.
        If deviceClass is Synthesizer or Sequencer, a device implementing
        the respective interface is considered appropriate. If deviceClass
        is Receiver or Transmitter, a device is considered appropriate if
        it implements neither Synthesizer nor Transmitter, and if it can
        provide at least one Receiver or Transmitter, respectively.

        @param device the MidiDevice to test
        @param allowSynthesizer if true, Synthesizers are considered
        appropriate. Otherwise only pure MidiDevices are considered
        appropriate (unless allowSequencer is true). This flag only has an
        effect for deviceClass Receiver and Transmitter. For other device
        classes (Sequencer and Synthesizer), this flag has no effect.
        @param allowSequencer if true, Sequencers are considered
        appropriate. Otherwise only pure MidiDevices are considered
        appropriate (unless allowSynthesizer is true). This flag only has an
        effect for deviceClass Receiver and Transmitter. For other device
        classes (Sequencer and Synthesizer), this flag has no effect.
        @return true if the device is considered appropriate according to the
        rules given above, false otherwise.
    */
    private static boolean isAppropriateDevice(MidiDevice device,
                                               Class deviceClass,
                                               boolean allowSynthesizer,
                                               boolean allowSequencer) {
        if (deviceClass.isInstance(device)) {
            // This clause is for deviceClass being either Synthesizer
            // or Sequencer.
            return true;
        } else {
            // Now the case that deviceClass is Transmitter or
            // Receiver. If neither allowSynthesizer nor allowSequencer is
            // true, we require device instances to be
            // neither Synthesizer nor Sequencer, since we only want
            // devices representing MIDI ports.
            // Otherwise, the respective type is accepted, too
            if ( (! (device instanceof Sequencer) &&
                  ! (device instanceof Synthesizer) ) ||
                 ((device instanceof Sequencer) && allowSequencer) ||
                 ((device instanceof Synthesizer) && allowSynthesizer)) {
                // And of cource, the device has to be able to provide
                // Receivers or Transmitters.
                if ((deviceClass == Receiver.class &&
                     device.getMaxReceivers() != 0) ||
                    (deviceClass == Transmitter.class &&
                     device.getMaxTransmitters() != 0)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Obtains the set of services currently installed on the system
     * using sun.misc.Service, the SPI mechanism in 1.3.
     * @return a List of instances of providers for the requested service.
     * If no providers are available, a List of length 0 will be returned.
     */
    private static List getProviders(Class providerClass) {
        return JDK13Services.getProviders(providerClass);
    }
}

redpajama_set_name: RedPajamaGithub


854 Cedar Lane is a $1,795,000, 2,500 square foot, 7 bedroom, 8.0 bath home on a 64.00 acre lot located in Brevard, NC.
Nestled among the Blue Ridge mountains and close to the continental divide sits a 64-acre mountain compound awaiting a new steward.Owned by one family for decades, this property boasts two houses, a 4-stall barn, pond and stream amid 64 rolling acres of undeveloped pasture and woods.The highest elevation knoll offers breathtaking views of the NC mountains.Located halfway between Caesars head, SC and Brevard, NC this mountain oasis is the perfect retreat for a discerning,conservation minded family.Both the log cabin and the guest house feature screen porches providing the perfect perch overlooking the tranquil pond.The cabin,built with 200 year old timbers, is an open floor plan and has hardwoods throughout and both homes have stone fire hearths.Quaint shops and fabulous restaurants are only 9 miles away in Brevard, and for the avid hiker, DuPont State Forest is an adventurer's dream.This tranquil retreat is a rare opportunity to experience the unspoiled magnificence of the mountains.
I am interested in 854 Cedar Lane, Brevard, NC 28712.


Find out from the gatekeepers the best ways to make it into the games industry. These experts will share tips on what to do to land a job and the red flags that get candidates denied. From ways to excel at your interview to how to get your resume past the recruiter screening, our experts will answer your questions to help you score the job of your dreams. Whether this is your first job in the industry or your fifth, you will gain insight on what recruiters and hiring managers love and hate about candidates.
Failure in the game industry can take a lot of different forms. You might get turned down for a team role you really wanted. You might not get the job. Your project might not be well-received by the public. Or your company might never take off. Join us for this informative and inspiring series of microtalks from people who have been there and done that. Learn from their "failures" and how they handled those experiences.
In this talk, James Portnow of Extra Credits discusses what it means to thrive, breaks down the elements of a thriving life and examines how we can deliver those through games. Aimed at new and experienced game designers and developers, this session looks at the tools and techniques that fulfill both fans and creators.
Abby Joslin (m), Maria Cahill, Susan Duralde, Curtis Hartung, Judy Suiter, Jonathan Wolfman.
Join industry representatives and college team captains for a roundtable discussion of how to attract the right people, the roles that must be filled, training techniques and more.
More session announcements to come.


playing a hand in holding back mass-production.
selected cities around the country."
electricity was the only technology at the time that filled the bill."
enviro-darling despite its limited driving range and other drawbacks.
GM's next wave of hybrid and other advanced vehicles."
make too many tradeoffs" in convenience and range."
sent them to the crusher for disposal."
rising interest in environmental concerns futher fueled this interest.
still portends hope for the future.
See "Timeline: Life & Death of the Electric Car."
attempt at manufacturing electric vehicles.
Arnold Schwarzenegger's senior adviser on energy and the environment.
when the power runs out."
under $30K is a minimum for a viable consumer vehicle."
From "Retro EVs Need More OoMPH." Atotopia. Wired Blogs.
"Electric Vehicles, the Cutting Edge Then and Now."
Stockholm School of Economics. 1996.
"TED Case Studies - The Electric Car. Number: 474"
Electric Vehicle: Technology and Expectations in the Automobile Age."
to give consumers the range they demand.
gas/electric car was developed in the very early 1900's.
were in cities, speeds were low, and distances were short.
Thank you so much for the five stars and generous tip, tosop!
searched in vain for a parking spot can testify.


text:
Schefflera kornasii är en araliaväxtart som beskrevs av Igor Vladimirovich Grushvitzky och Skvortzova. Schefflera kornasii ingår i släktet Schefflera och familjen araliaväxter.

Artens utbredningsområde är Vietnam. Inga underarter finns listade.

Källor

Araliaväxter
kornasii

redpajama_set_name: RedPajamaWikipedia


text:
EaP Summit
EU policy
YOUNG EUROPEAN AMBASSADORS
YEA Magazine
The latest news and information on the European Union's (EU) cooperation with its Eastern partners: Armenia, Azerbaijan, Belarus, Georgia, the Republic of Moldova and Ukraine
Shilda Winery: Energy Efficient Winery in Georgia
Shilda Winery has been operating from Shilda Village, in the Kakheti region of Georgia, for five years. The winery processes 2,000 tonnes of grapes each season, and produces approximately 1.4 million bottles of wine across 25 varieties.
By equipping itself with energy efficient technologies, the company was able to reduce its electricity consumption per unit produced by 50-60% and save EUR 63,000 (USD 72,000) per year. According to a representative from the winery, using energy efficient technologies has also improved Shilda's wine quality and had a positive effect on the environment.
Shilda Winery received a loan from a commercial bank as part of the EU-supported Energocredit programme. The money was used to replace 80% of the winery's existing equipment with energy efficient technologies, approved by the experts of Energocredit. This included processing, storage and sub-zero treatment equipment in the factory.
The company also received cashback from the Energocredit programme in the form of an EU grant (10% of the fee paid for the energy efficient equipment). This made the programme more affordable for small and medium-sized enterprises (SMEs).
Merab Mikashavidze, the director of Shilda Winery, has seen the benefits of the new equipment. "The energy consumption of our boiler, for example, is about 1.5 kilowatts now. The previous equipment – which is used by about 70% of wineries in Georgia – consumed 15 kilowatts. This meant it required 10 times the energy to do the same task."
Nika Tchitchadze, the head of technical support at the factory, agrees and explains that the new, energy efficient refrigerators have also been a great help, reducing electricity consumption from 500 kilowatts to 200 kilowatts per hour.
Tchitchadze notes that even lightbulbs inside the factory are energy efficient, with Shilda using LED lamps throughout instead of incandescent lightbulbs. He says that the latter consumes 1 kilowatts per hour of electricity, while the former only uses 200 watts, reducing costs five times over. What's more, LED lamps are more resilient to unstable voltage and last longer.
"When your factory is energy efficient, cost price for product lowers, which makes you more competitive in the market," Tchitchadze adds. "It also helps to improve your product quality, boost profits and allows you to enter new markets. When the owner makes a larger profit, workers' salaries increase too. It also affects the economy and energy resources of the country."
Shilda Winery has transcended Georgia's market and is gaining a foothold in the markets of Belgium, China, Kazakhstan, Russia and Ukraine. The company has also built a tourist site – a restaurant in the factory yard. The winery employs 61 people at the moment.
Mikheil Khmelidze is the chief winemaker at Shilda, with 22 years of experience in the field. He says the new equipment has made it easier for him to manage the technological process.
"It's very convenient. The equipment we have here is mostly from 2016-2017, which is important. Also, the diversity of the grape varieties is a great attraction for me. I work on local varieties such as Rkatsiteli, Khikhvi and Saperavi."
According to the company representatives, the factory plays an important role for locals as well, because 100% of the grapes they process come from local producers.
Tchitchadze believes that many companies do not realise the importance of energy efficiency, and programmes like Energocredit will encourage them to follow suit. "Somebody has to do it first so that people can see its significance and advantages. Otherwise, nobody is going to understand it and try it."
Shilda Winery
Energocredit for energy efficiency
The Energocredit programme was part of the EU4Energy Initiative and financed by the European Bank for Reconstruction and Development (EBRD), the EU and the Federal Ministry of Finance of Austria. The programme's aim was to support sustainable energy in Armenia, Azerbaijan and Georgia by providing loans to SMEs and citizens for projects designed to improve energy efficiency.
Giorgi Zurashvili, the head of projects at Energocredit Georgia, says that collaboration between the EU and EBRD started in 2012, when the EU showed its commitment to assisting the EBRD in encouraging investments in energy efficiency. He says EUR 108 million (USD 125 million) were provided in total, distributed among Armenia, Azerbaijan and Georgia. Most of these funds – EUR 69 million (USD 78 million) – was received by Georgia. Separate credit lines were assigned to entrepreneurial, commercial and civil borrowers for investments in energy efficiency and renewable energy. According to Zurashvili, approximately 50% of the funds were allocated to the consumer sector and the rest to businesses.
Clients who bought energy efficient products that complied with Energocredit criteria were provided with reimbursements ranging between 10% and 15% by the EU, as Zurashvili explains.
"If a company had an energy efficiency project that was ready to launch and took out a loan, then they would receive 10% cashback after using up that loan and completing the project. The cashback would be granted after experts had verified that the project was realised according to the programme's standards for energy efficiency."
There was also a second option. If a borrower had a project that did not meet Energocredit's criteria in terms of energy efficiency, they could ask for assistance in redefining the project. As a result, they would receive 15% subsidy from the EU to implement the recommended energy efficiency measures.
According to Zurashvili, bank clients (borrowers or not) were getting recommendations and energy audits from specialists for free and a significant number of organisations took advantage of that opportunity. He adds that in some countries, energy audits are mandatory for companies and they have to pay for the service.
"Those organisations that had energy audits conducted, later came up with a project and received the premium grant of 15% since they took our report into account," Zurashvili notes, adding that corporate clients presented diverse projects: hotel businesses, metallurgy companies, wineries, water and natural gas providers, etc. As for the companies, they saved different levels of energy through the equipment they bought, or increased their output while consuming the same amount of energy.
In addition to the companies, more than 40,000 families received loans to buy energy efficient home appliances. As a result, many more people became aware of the importance of sustainable and efficient energy.
Author: Basti Mgaloblishvili
Article on Liberali.ge
Energy, Environment, Transport
EU4Energy
'At our old age, all you need is a little amusement and peace, and here we have everything for that'
Three friends in Georgia had a dream business idea: EU4Youth helped them make it come true
Cancer support and independent media: how EU is helping local initiatives take off in Georgia
eSignature taking a step towards the digital future
eSignature: a key step connecting Georgia with the EU
Interested in the latest news and opportunities?
This website is managed by the EU-funded Regional Communication Programme for the Eastern Neighbourhood ('EU NEIGHBOURS east'), which complements and supports the communication of the Delegations of the European Union in the Eastern partner countries, and works under the guidance of the European Commission's Directorate-General for Neighbourhood Policy and Enlargement Negotiations, and the European External Action Service. EU NEIGHBOURS east is implemented by a B&S Europe-led consortium. It is part of the larger Neighbourhood Communication Programme (2020-2024) for the EU's Eastern and Southern Neighbourhood, which also includes 'EU NEIGHBOURS south' project that runs the EU Neighbours portal.
The information on this site is subject to a Disclaimer and Protection of personal data.
© European Union,


text:
Press Release: More Public Participation in Law Making Processes
ccf September 7, 2022 Current Programs, Media, Media Advocacy, Press Release
Participants at a CCF Human Rights Workshop.
Fiji's current trend of passing bills into law with little to no public participation and consultation is worrying, says the Citizens' Constitutional Forum (CCF) Chief Executive Officer Louchrisha Hussain as part of the organisation's Constitution Day message.
Today marks the 7th Fiji Constitution Day, a public holiday that began back in 2016, commemorating the adoption of the 2013 Constitution of the Republic of Fiji.
One of the purposes of the Constitution is to protect the rights of all citizens, and to establish and guide institutions through a system of checks and balances, to ensure that government does not take advantage of positions of power. The preamble recognizes the Constitution as the Supreme law of the country that provides the framework for the conduct of government and all citizens.
Ms. Hussain reiterated that any proposed changes to a law that affects citizens should undergo public consultation and adhere to proper principles of democracy.
"Fast tracking of bills into law disregards the very basis of a true democracy, and it is important for government to ensure that democratic due processes are followed. Certain freedoms under the Bill of Rights in the Constitution are limited by a number of ways and one being through written laws. If our rights can be limited in such a way, amongst others as stated in the Constitution, then this gives more reason for laws affecting citizens of Fiji to undergo a thorough consultative process."
When democratic due processes are followed, these allow for citizens to be aware or, made aware and understand exactly what is being proposed to become a law and how it will affect them.
CCF believes that Constitutions should set the foundation for the promotion and protection of democracy, especially the rights and freedoms of citizens, and that it should be realised through proper democratic implementation and course of action on the ground.
Over the years, CCF has emphasized the importance of government systems and processes being inclusive of all citizens.
Ms. Hussain says, "We need to take the time to read and understand the Constitution, and how it affects every aspect of our lives."
Understanding the Constitution will allow citizens to not only demand for the protection and promotion of basic human rights but also allow citizens to make informed decisions that have a wide reaching impact on their communities and the nation.
As part of its' ongoing efforts to create awareness and understanding amongst citizens, the CCF community education and advocacy team, implements education awareness workshops around the country on the Bill of Rights as stipulated under Section 2 of the 2013 Constitution of the Republic of Fiji.
"We support the promotion, respect and protection of human rights and fundamental freedoms whilst promoting multiculturalism, good governance and the rule of law. These are key elements to bringing about prosperity in all aspects of development in Fiji. "
CCF Citizens' Constitutional Forum Fiji media


text:
CompaniesTeamAdvisorsApproachNewsroom
LP LoginPrivacy PolicyPress Kit
« Back to Team
Donald Dixon
Our mission is clear: to protect our nation, spur global innovation, and advance the progress of mankind. Backing the best teams in cybersecurity is how we deliver.
Don is a Co-Founder and Managing Director at Forgepoint. He has been a technology investor for over 30 years and was one of the earliest investors in cybersecurity.
Prior to Forgepoint, Don led Trident Capital for over 20 years. Prior to Trident, Don was the Co-President at Partech International, a Managing Director at Alex. Brown & Sons, and a Vice President at Morgan Stanley.
Don is a member of the Advisory Board of the Princeton School of Engineering and Applied Sciences and the Harvard Kennedy School Center for Public Leadership. He is also a Director for the Business Executives for National Security (BENS), and a member of the Aspen Institute's Cybersecurity Group, the nation's leading cross-sector public-private cybersecurity forum that aims to translate pressing cybersecurity conversations into action. Previously, Don was a Board member of the Naval Postgraduate School.
Don holds an MBA from Stanford's Graduate School of Business and a BSE from Princeton University. When not in the office, you can find Don rowing his open water scull across Lake Tahoe.
Current Investments
Bishop Fox
Concourse Labs
CyberCube
IronNet Cybersecurity (NYSE: IRNT)
SolCyber
Verituity
WireWheel
Prior Investments
Merchant e-Solutions (acquired by Cielo)
Neohapsis (acquired by Cisco)
Qualys (NASDAQ: QLYS)
Signio (acquired by VeriSign)
Sygate Technologies (acquired by Symantec)
400 S El Camino Real, Suite 1050
San Mateo, California 94402
Subscribe to the Forgepoint newsletter:
© Forgepoint Capital. All rights reserved. LP LoginPrivacy PolicyPress Kit


text:
Matter & Energy
Science Bulletin
Home Chemistry The seed that could bring clean water to millions
The seed that could bring clean water to millions
According to the United Nations, 2.1 billion people lack access to safely managed drinking water services, the majority of whom live in developing nations.
Carnegie Mellon University's Biomedical Engineering and Chemical Engineering Professors Bob Tilton and Todd Przybycien recently co-authored a paper with Ph.D. students Brittany Nordmark and Toni Bechtel, and alumnus John Riley, further refining a process that could soon help provide clean water to many in water-scarce regions. The process, created by Tilton's former student and co-author Stephanie Velegol, uses sand and plant materials readily available in many developing nations to create a cheap and effective water filtration medium, termed "f-sand."
"F-sand" uses proteins from the Moringa oleifera plant, a tree native to India that grows well in tropical and subtropical climates. The tree is cultivated for food and natural oils, and the seeds are already used for a type of rudimentary water purification. However, this traditional means of purification leaves behind high amounts of dissolved organic carbon (DOC) from the seeds, allowing bacteria to regrow after just 24 hours. This leaves only a short window in which the water is drinkable.
Velegol, who is now a professor of chemical engineering at Penn State University, had the idea to combine this method of water purification with sand filtration methods common in developing areas. By extracting the seed proteins and adsorbing (adhering) them to the surface of silica particles, the principal component of sand, she created f-sand. F-sand both kills microorganisms and reduces turbidity, adhering to particulate and organic matter. These undesirable contaminants and DOC can then be washed out, leaving the water clean for longer, and the f-sand ready for reuse.
While the basic process was proven and effective, there were still many questions surrounding f-sand's creation and use—questions Tilton and Przybycien resolved to answer.
Would isolating certain proteins from the M. oleifera seeds increase f-sand's effectiveness? Are the fatty acids and oils found in the seeds important to the adsorption process? What effect would water conditions have? What concentration of proteins is necessary to create an effective product?
The answers to these questions could have big implications on the future of f-sand.
The seed of M. oleifera contains at least eight different proteins. Separating these proteins, a process known as fractionation, would introduce another step to the process. Prior to their research, the authors theorized that isolating certain proteins might provide a more efficient finished product.
However, through the course of testing, Tilton and Przybycien found that this was not the case. Fractionating the proteins had little discernible effect on the proteins' ability to adsorb to the silica particles, meaning this step was unnecessary to the f-sand creation process.
The finding that fractionation is unnecessary is particularly advantageous to the resource-scarce scenario in which f-sand is intended to be utilized. Leaving this step out of the process helps cut costs, lower processing requirements, and simplify the overall process.
One of the major reasons M. oleifera is cultivated currently is for the fatty acids and oils found in the seeds. These are extracted and sold commercially. Tilton and Przybycien were interested to know if these fatty acids had an effect on the protein adsorption process as well.
They found that much like fractionation, removing the fatty acids had little effect on the ability of the proteins to adsorb. This finding also has beneficial implications for those wishing to implement this process in developing regions. Since the presence or absence of fatty acids in the seeds has little effect on the creation or function of f-sand, people in the region can remove and sell the commercially valuable oil, and still be able to extract the proteins from the remaining seeds for water filtration.
Another parameter of the f-sand manufacturing process that Tilton and Przybycien tested was the concentration of seed proteins needed to create an effective product. The necessary concentration has a major impact on the amount of seeds required, which in turn has a direct effect on overall efficiency and cost effectiveness.
The key to achieving the proper concentration is ensuring that there are enough positively charged proteins to overcome the negative charge of the silica particles to which they are attached, creating a net positive charge. This positive charge is crucial to attract the negatively charged organic matter, particulates, and microbes contaminating the water.
This relates to another potential improvement to drinking water treatment investigated by Tilton, Przybycien, and Nordmark in a separate publication. In this project, they used seed proteins to coagulate contaminants in the water prior to f-sand filtration. This also relies on controlling the charge of the contaminants, which coagulate when they are neutralized. Applying too much protein can over-charge the contaminants and inhibit coagulation.
"There's kind of a sweet spot in the middle," says Tilton, "and it lies in the details of how the different proteins in these seed protein mixtures compete with each other for adsorption to the surface, which tended to broaden that sweet spot."
This broad range of concentrations means that not only can water treatment processes be created at relatively low concentrations, thereby conserving materials, but that there is little risk of accidentally causing water contamination by overshooting the concentration. In areas where exact measurements may be difficult to make, this is crucial.
Water hardness refers to the amount of dissolved minerals in the water. Although labs often use deionized water, in a process meant to be applied across a range of real world environments, researchers have to prepare for both soft and hard water conditions.
Tilton and Przybycien found that proteins were able to adsorb well to the silica particles, and to coagulate suspended contaminants, in both soft and hard water conditions. This means that the process could potentially be viable across a wide array of regions, regardless of water hardness.
Tilton and Przybycien recently published a paper on this research, "Moringa oleifera Seed Protein Adsorption to Silica: Effects of Water Hardness, Fractionation, and Fatty Acid Extraction," in ACS Langmuir.
Overall, the conclusions that Tilton, Przybycien, and their fellow authors were able to reach have major benefits for those in developing countries looking for a cheap and easily accessible form of water purification. Their work puts this novel innovation one step closer to the field, helping to forge the path that may one day see f-sand deployed in communities across the developing world. They've shown that the f-sand manufacturing process displays a high degree of flexibility, as it is able to work at a range of water conditions and protein concentrations without requiring the presence of fatty acids or a need for fractionation.
"It's an area where complexity could lead to failure—the more complex it is, the more ways something could go wrong," says Tilton. "I think the bottom line is that this supports the idea that the simpler technology might be the better one."
Carnegie Mellon University, Department of Chemical Engineering
Brittany A. Nordmark et al. Moringa oleifera Seed Protein Adsorption to Silica: Effects of Water Hardness, Fractionation, and Fatty Acid Extraction. Langmuir (2018). DOI: 10.1021/acs.langmuir.8b00191
(left) Unshelled M. oleifera seeds, (middle) shelled seeds, (right) crushed seeds before protein extraction
Credit: Carnegie Mellon University College of Engineering
Previous articleOrange, tea tree and eucalyptus oils sweeten diesel fumes
Next articleInterfacing with the brain
Researchers create new form of cultivated meat
Rethinking spin chemistry from a quantum perspective
Conductive nature in crystal structures revealed at magnification of 10 million times
Join over 25,000 of your peers and be in the know.
sciencebulletin
What goes on in the sun can only be observed indir
Sixteen years of remote sensing data reveals that
A McGill-led research team has identified a new sp
Trapped in amber for ~100 million years, an except
Scientists have combined NASA data and cutting-edg
Even if you weren't a physics major, you've probab
Researchers from the University of Cambridge have
Researchers at Osaka City University use quantum s
More than 3,000 animal species in the world today
Future climate change will cause a regionally unev
The core mass of the giant exoplanet WASP-107b is
A team of scientists from the Leibniz Institute fo
In a new study, Stanford researchers report that i
Galaxies begin to "die" when they stop forming sta
Researchers have for the first time identified the
COVID-19 report, photo concept (stock image).Credi
Habitat destruction by logging and agriculture is
A new study, led by a theoretical physicist at the
Solar activity reconstructed over a millennium
World's largest lakes reveal climate change trends
Discovery of new praying mantis species from the time of the...
Astronomy & Space1875
Physics1572
Animals & Plants1232
Biology1165
Earth Science734
Chemistry679
© Copyright 2019 ScienceBulletin
Get the Most Popular Science News in your inbox:
Sign up for our weekly email and get the best and most interesting science stories in your inbox
we promise never to spam you!


text:
Q: Configuring Jersey to provide a WADL through JSON So Jersey's default WADL functionality is great! Except if your developing your API to only handle JSON at which point it seems a little silly to force your client apps to switch back to XML for the WADL.
Could anyone provide (or point me to) an example of how to get Jersey to produce a JSON representation of the WADL document?
Thanks in advance.

A: There is a patch for Jersey now
Jersey JSON WADL patch

redpajama_set_name: RedPajamaStackExchange


Rose cut modern amethyst stone set in a handmade sterling silver setting with small ball accents. The chain is sterling silver and measures 19" (48.2 cm) long. The pendant is 1 7/8" (4.8 cm) long and is 1 1/8" (2.8 cm) wide. Amethyst is the birthstone for February and the traditional gift for the 33rd wedding anniversary.
First Class shipping is free, with upgraded and international shipping available.


Do you want to use Word more efficiently and successfully? Discover the word-processing program with its wide range of options. Soon you will be able to create, design and print documents, forms, mail merge letters or labels easily and efficiently.
The course can be started at any time and you determine your own pace. Thanks to a combination of video lessons and exercises in the virtual Office application, you can practise and use the knowledge you have gained immediately. The digital reference materials provide an additional teaching aid so that you can learn about the topics in more detail. You can view your learning outcomes in detail, giving you control of your progress and making it easy to determine your learning process.
Expand your knowledge of Word with this online course – from anywhere, at any time!
Learn about all the features of Word with this online course – from anywhere, at any time!
Learn the basics of Word with this online course – from anywhere, at any time!
Learn about the new features of Word 2016 with this online course – from anywhere, at any time!