text:
package de.sciss.net;

import java.io.IOException;
import java.io.PrintStream;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SocketChannel;

/**
 *  A class that sends OSC packets (messages
 *	or bundles) to a target OSC server. Each instance takes
 *	a network channel, either explictly specified by a
 *	DatagramChannel (for UDP) or SocketChannel (for TCP),
 *	or internally opened when a protocol type is specified.
 *

 *	Messages are send by invoking one
 *	of the send methods. For an example,
 *	please refer to the OSCReceiver document.
 *

 *	Note that as of v0.3, you will most likely want to use preferably one of OSCClient or OSCServer
 *	over OSCTransmitter. Also note that as of v0.3, OSCTransmitter is abstract, which
 *	renders direct instantiation impossible. To update old code, occurences of new OSCTransmitter()
 *	must be replaced by one of the OSCTransmitter.newUsing methods!
 *

 *	Note that someone has reported trouble with the InetAddress.getLocalHost() method
 *	on a machine that has no proper IP configuration or DNS problems. In such a case when you need
 *	to communicate only on this machine and not a network, you can still bind the channel
 *	to the special address "127.0.0.1" (called "loopback").
 *
 *  @author		Hanns Holger Rutz
 *  @version	0.33, 05-Mar-09
 *
 *	@see				OSCClient
 *	@see				OSCServer
 *	@see				OSCReceiver
 *
 *	@synchronization	sending messages is thread safe
 *	@todo				an explicit disconnect method might be useful
 *						(this is implicitly done when calling dispose)
 */
public abstract class OSCTransmitter
implements OSCChannel
{
	protected final Object				sync			= new Object();	// buffer (re)allocation
	protected boolean					allocBuf		= true;
	private int							bufSize			= DEFAULTBUFSIZE;
	protected ByteBuffer				byteBuf			= null;

    protected int						dumpMode		= kDumpOff;
    protected PrintStream				printStream		= null;

	private OSCPacketCodec				c;
	private final String				protocol;

	protected SocketAddress				target			= null;

	protected final InetSocketAddress	localAddress;
	protected final boolean				revivable;

	protected OSCTransmitter( OSCPacketCodec c, String protocol, InetSocketAddress localAddress, boolean revivable )
	{
		this.c				= c;
		this.protocol		= protocol;
		this.localAddress	= localAddress;
		this.revivable		= revivable;
	}

	/**
	 *	Creates a new instance of an OSCTransmitter, using
	 *	default codec and a specific transport protocol. It picks an arbitrary free port
	 *	and uses the local machine's IP. To determine the resulting
	 *	port, you can use getLocalAddress afterwards.
	 *
	 *	@param	protocol	the protocol to use, currently either UDP or TCP
	 *	@return				the newly created transmitter
	 *
	 *	@throws	IOException					if a networking error occurs while creating the socket
	 *	@throws	IllegalArgumentException	if an illegal protocol is used
	 *
	 *	@see	OSCChannel#UDP
	 *	@see	OSCChannel#TCP
	 *	@see	#getLocalAddress
	 */
	public static OSCTransmitter newUsing( String protocol )
	throws IOException
	{
		return newUsing( OSCPacketCodec.getDefaultCodec(), protocol );
	}

	/**
	 *	Creates a new instance of an OSCTransmitter, using
	 *	a specific codec and transport protocol. It picks an arbitrary free port
	 *	and uses the local machine's IP. To determine the resulting
	 *	port, you can use getLocalAddress afterwards.
	 *
	 *	@param	c			the codec to use
	 *	@param	protocol	the protocol to use, currently either UDP or TCP
	 *	@return				the newly created transmitter
	 *
	 *	@throws	IOException					if a networking error occurs while creating the socket
	 *	@throws	IllegalArgumentException	if an illegal protocol is used
	 *
	 *	@see	OSCChannel#UDP
	 *	@see	OSCChannel#TCP
	 *	@see	#getLocalAddress
	 *
	 *	@since		NetUtil 0.33
	 */
	public static OSCTransmitter newUsing( OSCPacketCodec c, String protocol )
	throws IOException
	{
		return newUsing( c, protocol, 0 );
	}

	/**
	 *	Creates a new instance of an OSCTransmitter, using
	 *	default codec and a specific transport protocol and port. It
	 *	uses the local machine's IP. Note that the port specifies the
	 *	local socket, not the remote (or target) port. This can be set
	 *	using the setTarget method!
	 *
	 *	@param	protocol	the protocol to use, currently either UDP or TCP
	 *	@param	port		the port number for the OSC socket, or 0 to use an arbitrary free port
	 *	@return				the newly created transmitter
	 *
	 *	@throws	IOException					if a networking error occurs while creating the socket
	 *	@throws	IllegalArgumentException	if an illegal protocol is used
	 */
	public static OSCTransmitter newUsing( String protocol, int port )
	throws IOException
	{
		return newUsing( OSCPacketCodec.getDefaultCodec(), protocol, port );
	}

	/**
	 *	Creates a new instance of an OSCTransmitter, using
	 *	a specific codec and transport protocol and port. It
	 *	uses the local machine's IP. Note that the port specifies the
	 *	local socket, not the remote (or target) port. This can be set
	 *	using the setTarget method!
	 *
	 *	@param	c			the codec to use
	 *	@param	protocol	the protocol to use, currently either UDP or TCP
	 *	@param	port		the port number for the OSC socket, or 0 to use an arbitrary free port
	 *	@return				the newly created transmitter
	 *
	 *	@throws	IOException					if a networking error occurs while creating the socket
	 *	@throws	IllegalArgumentException	if an illegal protocol is used
	 *
	 *	@since		NetUtil 0.33
	 */
	public static OSCTransmitter newUsing( OSCPacketCodec c, String protocol, int port )
	throws IOException
	{
		return newUsing( c, protocol, port, false );
	}

	/**
	 *	Creates a new instance of an OSCTransmitter, using
	 *	default codec and a specific transport protocol and port. It
	 *	uses the local machine's IP or the "loopback" address.
	 *	Note that the port specifies the
	 *	local socket, not the remote (or target) port. This can be set
	 *	using the setTarget method!
	 *
	 *	@param	protocol	the protocol to use, currently either UDP or TCP
	 *	@param	port		the port number for the OSC socket, or 0 to use an arbitrary free port
	 *	@param	loopBack	if true, the "loopback" address ("127.0.0.1")
	 *						is used which limits communication to the local machine. If false, the
	 *						local machine's regular IP address is used.
	 *
	 *	@return				the newly created transmitter
	 *
	 *	@throws	IOException					if a networking error occurs while creating the socket
	 *	@throws	IllegalArgumentException	if an illegal protocol is used
	 */
	public static OSCTransmitter newUsing( String protocol, int port, boolean loopBack )
	throws IOException
	{
		return newUsing( OSCPacketCodec.getDefaultCodec(), protocol, port, loopBack );
	}

	/**
	 *	Creates a new instance of an OSCTransmitter, using
	 *	a specific codec and transport protocol and port. It
	 *	uses the local machine's IP or the "loopback" address.
	 *	Note that the port specifies the
	 *	local socket, not the remote (or target) port. This can be set
	 *	using the setTarget method!
	 *
	 *	@param	c			the codec to use
	 *	@param	protocol	the protocol to use, currently either UDP or TCP
	 *	@param	port		the port number for the OSC socket, or 0 to use an arbitrary free port
	 *	@param	loopBack	if true, the "loopback" address ("127.0.0.1")
	 *						is used which limits communication to the local machine. If false, the
	 *						local machine's regular IP address is used.
	 *
	 *	@return				the newly created transmitter
	 *
	 *	@throws	IOException					if a networking error occurs while creating the socket
	 *	@throws	IllegalArgumentException	if an illegal protocol is used
	 *
	 *	@since		NetUtil 0.33
	 */
	public static OSCTransmitter newUsing( OSCPacketCodec c, String protocol, int port, boolean loopBack )
	throws IOException
	{
      //XXX alex changed the InetSocketAddress to just take the port, works on android now
      final InetSocketAddress localAddress = loopBack ? new InetSocketAddress( "127.0.0.1", port ) :
         new InetSocketAddress( port );
         //new InetSocketAddress( InetAddress.getLocalHost(), port );
		return newUsing( c, protocol, localAddress );
	}

	/**
	 *	Creates a new instance of an OSCTransmitter, using
	 *	default codec and a specific transport protocol and local socket address.
	 *	Note that localAddress specifies the
	 *	local socket, not the remote (or target) socket. This can be set
	 *	using the setTarget method!
	 *
	 *	@param	protocol		the protocol to use, currently either UDP or TCP
	 *	@param	localAddress	a valid address to use for the OSC socket. If the port is 0,
	 *							an arbitrary free port is picked when the transmitter is connected. (you can find out
	 *							the actual port in this case by calling getLocalAddress() after the
	 *							transmitter was connected).
	 *
	 *	@return					the newly created transmitter
	 *
	 *	@throws	IOException					if a networking error occurs while creating the socket
	 *	@throws	IllegalArgumentException	if an illegal protocol is used
	 */
	public static OSCTransmitter newUsing( String protocol, InetSocketAddress localAddress )
	throws IOException
	{
		return newUsing( OSCPacketCodec.getDefaultCodec(), protocol, localAddress );
	}

	/**
	 *	Creates a new instance of an OSCTransmitter, using
	 *	a specific codec and transport protocol and local socket address.
	 *	Note that localAddress specifies the
	 *	local socket, not the remote (or target) socket. This can be set
	 *	using the setTarget method!
	 *
	 *	@param	c				the codec to use
	 *	@param	protocol		the protocol to use, currently either UDP or TCP
	 *	@param	localAddress	a valid address to use for the OSC socket. If the port is 0,
	 *							an arbitrary free port is picked when the transmitter is connected. (you can find out
	 *							the actual port in this case by calling getLocalAddress() after the
	 *							transmitter was connected).
	 *
	 *	@return					the newly created transmitter
	 *
	 *	@throws	IOException					if a networking error occurs while creating the socket
	 *	@throws	IllegalArgumentException	if an illegal protocol is used
	 *
	 *	@since		NetUtil 0.33
	 */
	public static OSCTransmitter newUsing( OSCPacketCodec c, String protocol, InetSocketAddress localAddress )
	throws IOException
	{
		if( protocol.equals( UDP )) {
			return new UDPOSCTransmitter( c, localAddress );

		} else if( protocol.equals( TCP )) {
			return new TCPOSCTransmitter( c, localAddress );

		} else {
			throw new IllegalArgumentException( NetUtil.getResourceString( "errUnknownProtocol" ) + protocol );
		}
	}

	/**
	 *	Creates a new instance of an OSCTransmitter, using
	 *	default codec and UDP transport on a given channel. The caller should ensure that
	 *	the provided channel's socket was bound to a valid address
	 *	(using dch.socket().bind( SocketAddress )).
	 *	Note that dch specifies the
	 *	local socket, not the remote (or target) socket. This can be set
	 *	using the setTarget method!
	 *
	 *	@param	dch			the DatagramChannel to use as UDP socket.
	 *	@return				the newly created transmitter
	 *
	 *	@throws	IOException	if a networking error occurs while configuring the socket
	 */
	public static OSCTransmitter newUsing( DatagramChannel dch )
	throws IOException
	{
		return newUsing( OSCPacketCodec.getDefaultCodec(), dch );
	}

	/**
	 *	Creates a new instance of an OSCTransmitter, using
	 *	a specific codec and UDP transport on a given channel. The caller should ensure that
	 *	the provided channel's socket was bound to a valid address
	 *	(using dch.socket().bind( SocketAddress )).
	 *	Note that dch specifies the
	 *	local socket, not the remote (or target) socket. This can be set
	 *	using the setTarget method!
	 *
	 *	@param	c			the codec to use
	 *	@param	dch			the DatagramChannel to use as UDP socket.
	 *	@return				the newly created transmitter
	 *
	 *	@throws	IOException	if a networking error occurs while configuring the socket
	 *
	 *	@since		NetUtil 0.33
	 */
	public static OSCTransmitter newUsing( OSCPacketCodec c, DatagramChannel dch )
	throws IOException
	{
		return new UDPOSCTransmitter( c, dch );
	}

	/**
	 *	Creates a new instance of an OSCTransmitter, using
	 *	default codec and TCP transport on a given channel. The caller should ensure that
	 *	the provided channel's socket was bound to a valid address
	 *	(using sch.socket().bind( SocketAddress )). Furthermore,
	 *	the channel must be connected (using connect()) before
	 *	being able to transmit messages.
	 *	Note that sch specifies the
	 *	local socket, not the remote (or target) socket. This can be set
	 *	using the setTarget method!
	 *
	 *	@param	sch			the SocketChannel to use as TCP socket.
	 *	@return				the newly created transmitter
	 *
	 *	@throws	IOException	if a networking error occurs while configuring the socket
	 */
	public static OSCTransmitter newUsing( SocketChannel sch )
	throws IOException
	{
		return newUsing( OSCPacketCodec.getDefaultCodec(), sch );
	}

	/**
	 *	Creates a new instance of an OSCTransmitter, using
	 *	a specific codec and TCP transport on a given channel. The caller should ensure that
	 *	the provided channel's socket was bound to a valid address
	 *	(using sch.socket().bind( SocketAddress )). Furthermore,
	 *	the channel must be connected (using connect()) before
	 *	being able to transmit messages.
	 *	Note that sch specifies the
	 *	local socket, not the remote (or target) socket. This can be set
	 *	using the setTarget method!
	 *
	 *	@param	c			the codec to use
	 *	@param	sch			the SocketChannel to use as TCP socket.
	 *	@return				the newly created transmitter
	 *
	 *	@throws	IOException	if a networking error occurs while configuring the socket
	 *
	 *	@since		NetUtil 0.33
	 */
	public static OSCTransmitter newUsing( OSCPacketCodec c, SocketChannel sch )
	throws IOException
	{
		return new TCPOSCTransmitter( c, sch );
	}

	public String getProtocol()
	{
		return protocol;
	}

	/**
	 *	Queries the transmitter's local socket address.
	 *	You can determine the host and port from the returned address
	 *	by calling getHostName() (or for the IP getAddress().getHostAddress())
	 *	and getPort(). This port number may be 0
	 *	if the transmitter was called with an unspecified port and has not yet been
	 *	connected. In this case, to determine the port actually used, call this
	 *	method after the transmitter has been connected.
	 *
	 *	@return				the address of the transmitter's local socket.
	 *
	 *	@see	java.net.InetSocketAddress#getHostName()
	 *	@see	java.net.InetSocketAddress#getAddress()
	 *	@see	java.net.InetSocketAddress#getPort()
	 */
	public abstract InetSocketAddress getLocalAddress();

	/**
	 *	Specifies the transmitter's target address, that is the address of the remote side to talk to.
	 *	You should call this method only once and you must call it before starting to
	 *	send messages using the shortcut call send( OSCPacket ).
	 *
	 *	@param	target	the address of the remote target socket. Usually you construct an appropriate InetSocketAddress
	 *
	 *	@see	InetSocketAddress
	 */
	public void setTarget( SocketAddress target )
	{
		this.target	= target;
	}

	public void setCodec( OSCPacketCodec c )
	{
		this.c	= c;
	}

	public OSCPacketCodec getCodec()
	{
		return c;
	}

	/**
	 *	Establishes connection for transports requiring
	 *	connectivity (e.g. TCP). For transports that do not require connectivity (e.g. UDP),
	 *	this ensures the communication channel is created and bound.
	 *

	 *	When a UDP transmitter
	 *	is created without an explicit DatagramChannel – say by
	 *	calling OSCTransmitter.newUsing( "udp" ), you are required
	 *	to call connect() so that an actual DatagramChannel is
	 *	created and bound. For a UDP transmitter which was created with an explicit
	 *	DatagramChannel, this method does noting, so it is always safe
	 *	to call connect(). However, for TCP transmitters,
	 *	this may throw an IOException if the transmitter
	 *	was already connected, therefore be sure to check isConnected() before.
	 *
	 *	@throws	IOException	if a networking error occurs. Possible reasons: - the underlying
	 *						network channel had been closed by the server. - the transport
	 *						is TCP and the server is not available. - the transport is TCP
	 *						and an OSCReceiver sharing the same socket was stopped before (unable to revive).
	 *
	 *	@see	#isConnected()
	 */
	public abstract void connect() throws IOException;

	/**
	 *	Queries the connection state of the transmitter.
	 *
	 *	@return	true if the transmitter is connected, false otherwise. For transports that do not use
	 *			connectivity (e.g. UDP) this returns false, if the
	 *			underlying DatagramChannel has not yet been created.
	 *
	 *	@see	#connect()
	 */
	public abstract boolean isConnected();

	/**
	 *	Sends an OSC packet (bundle or message) to the given
	 *	network address, using the current codec.
	 *
	 *	@param	p		the packet to send
	 *	@param	target	the target address to send the packet to
	 *
	 *	@throws	IOException	if a write error, OSC encoding error,
	 *						buffer overflow error or network error occurs
	 */
	public final void send( OSCPacket p, SocketAddress target )
	throws IOException
	{
		send( c, p, target );
	}

	/**
	 *	Sends an OSC packet (bundle or message) to the given
	 *	network address, using a particular codec.
	 *
	 *	@param	c			the codec to use
	 *	@param	p			the packet to send
	 *	@param	target		the target address to send the packet to
	 *
	 *	@throws	IOException	if a write error, OSC encoding error,
	 *						buffer overflow error or network error occurs
	 *
	 *	@since		NetUtil 0.33
	 */
	public abstract void send( OSCPacketCodec c, OSCPacket p, SocketAddress target ) throws IOException;

	/**
	 *	Sends an OSC packet (bundle or message) to the default
	 *	network address, using the current codec. The default address is the one specified
	 *	using the setTarget method. Therefore
	 *	this will throw a NullPointerException if
	 *	no default address was specified.
	 *
	 *	@param	p		the packet to send
	 *
	 *	@throws	IOException				if a write error, OSC encoding error,
	 *									buffer overflow error or network error occurs
	 *	@throws	NullPointerException	if no default address was specified
	 *
	 *	@see	#setTarget( SocketAddress )
	 */
	public final void send( OSCPacket p )
	throws IOException
	{
		send( p, target );
	}

	/**
	 *	Sends an OSC packet (bundle or message) to the default
	 *	network address, using a particular codec. The default address is the one specified
	 *	using the setTarget method. Therefore
	 *	this will throw a NullPointerException if
	 *	no default address was specified.
	 *
	 *	@param	c			the codec to use
	 *	@param	p			the packet to send
	 *
	 *	@throws	IOException				if a write error, OSC encoding error,
	 *									buffer overflow error or network error occurs
	 *	@throws	NullPointerException	if no default address was specified
	 *
	 *	@see	#setTarget( SocketAddress )
	 *
	 *	@since		NetUtil 0.33
	 */
	public abstract void send( OSCPacketCodec c, OSCPacket p ) throws IOException;

	public void setBufferSize( int size )
	{
		synchronized( sync ) {
			if( bufSize != size ) {
				bufSize		= size;
				allocBuf	= true;
			}
		}
	}

	public int getBufferSize()
	{
		synchronized( sync ) {
			return bufSize;
		}
	}

	public void dumpOSC( int mode, PrintStream stream )
	{
		this.dumpMode		= mode;
		this.printStream	= stream == null ? System.err : stream;
	}

	public void dispose()
	{
		byteBuf	= null;
	}

	// @synchronization	caller must ensure synchronization
	protected void checkBuffer()
	{
		if( allocBuf ) {
			byteBuf		= ByteBuffer.allocateDirect( bufSize );
			allocBuf	= false;
		}
	}

	protected abstract SelectableChannel getChannel();

//	protected abstract void setChannel( SelectableChannel ch );

	// --------------------- internal classes ---------------------

	private static class UDPOSCTransmitter
	extends OSCTransmitter
	{
		private DatagramChannel	dch;

		protected UDPOSCTransmitter( OSCPacketCodec c, InetSocketAddress localAddress )
		{
			super( c, UDP, localAddress, true );
		}

		protected UDPOSCTransmitter( OSCPacketCodec c, DatagramChannel dch )
		{
			super( c, UDP, new InetSocketAddress( dch.socket().getLocalAddress(), dch.socket().getLocalPort() ), false );

			this.dch	= dch;
		}

//		protected void setChannel( SelectableChannel ch )
//		{
//			dch	= (DatagramChannel) ch;
//		}

		protected SelectableChannel getChannel()
		{
			synchronized( sync ) {
				return dch;
			}
		}

		public InetSocketAddress getLocalAddress()
		{
			synchronized( sync ) {
				if( dch != null ) {
					final DatagramSocket ds = dch.socket();
					return new InetSocketAddress( ds.getLocalAddress(), ds.getLocalPort() );
				} else {
					return localAddress;
				}
			}
		}

		public void connect()
		throws IOException
		{
			synchronized( sync ) {
				if( (dch != null) && !dch.isOpen() ) {
					if( !revivable ) throw new IOException( NetUtil.getResourceString( "errCannotRevive" ));
					dch = null;
				}
				if( dch == null ) {
					final DatagramChannel newCh = DatagramChannel.open();
					newCh.socket().bind( localAddress );
					dch = newCh;
				}
			}
		}

		public boolean isConnected()
		{
			synchronized( sync ) {
				return( (dch != null) && dch.isOpen() );
			}
		}

		public void dispose()
		{
			super.dispose();
			if( dch != null ) {
				try {
					dch.close();
				}
				catch( IOException e1 ) { /* ignored */ }
				dch = null;
			}
		}

		public void send( OSCPacketCodec c, OSCPacket p )
		throws IOException
		{
			send( c, p, target );
		}

		public void send( OSCPacketCodec c, OSCPacket p, SocketAddress target )
		throws IOException
		{
			try {
				synchronized( sync ) {
//					if( dch == null ) throw new NotYetConnectedException();
					if( dch == null ) throw new IOException( NetUtil.getResourceString( "errChannelNotConnected" ));

					checkBuffer();
					byteBuf.clear();
					c.encode( p, byteBuf );
					byteBuf.flip();

					if( dumpMode != kDumpOff ) {
						printStream.print( "s: " );
						if( (dumpMode & kDumpText) != 0 ) OSCPacket.printTextOn( printStream, p );
						if( (dumpMode & kDumpHex)  != 0 ) {
							OSCPacket.printHexOn( printStream, byteBuf );
							byteBuf.flip();
						}
					}

					dch.send( byteBuf, target );
				}
			}
			catch( BufferOverflowException e1 ) {
				throw new OSCException( OSCException.BUFFER,
					p instanceof OSCMessage ? ((OSCMessage) p).getName() : p.getClass().getName() );
			}
		}
	}

	private static class TCPOSCTransmitter
	extends OSCTransmitter
	{
		private SocketChannel sch;

		protected TCPOSCTransmitter( OSCPacketCodec c, InetSocketAddress localAddress )
		{
			super( c, TCP, localAddress, true );
		}

		protected TCPOSCTransmitter( OSCPacketCodec c, SocketChannel sch )
		{
			super( c, TCP, new InetSocketAddress( sch.socket().getLocalAddress(), sch.socket().getLocalPort() ), false );

			this.sch	= sch;

			if( sch.isConnected() ) setTarget( sch.socket().getRemoteSocketAddress() );
		}

		public InetSocketAddress getLocalAddress()
		{
			synchronized( sync ) {
				if( sch != null ) {
					final Socket s = sch.socket();
					return new InetSocketAddress( s.getLocalAddress(), s.getLocalPort() );
				} else {
					return localAddress;
				}
			}
		}

//		protected void setChannel( SelectableChannel ch )
//		{
//			sch	= (SocketChannel) ch;
//		}

		protected SelectableChannel getChannel()
		{
			synchronized( sync ) {
				return sch;
			}
		}

		public void connect()
		throws IOException
		{
			synchronized( sync ) {
				if( (sch != null) && !sch.isOpen() ) {
					if( !revivable ) throw new IOException( NetUtil.getResourceString( "errCannotRevive" ));
					sch = null;
				}
				if( sch == null ) {
					final SocketChannel newCh = SocketChannel.open();
					newCh.socket().bind( localAddress );
					sch = newCh;
				}
				if( !sch.isConnected() ) {
					sch.connect( target );
				}
			}
		}

//		protected void disconnect()
//		throws IOException
//		{
//
//		}

		public boolean isConnected()
		{
			synchronized( sync ) {
				return( (sch != null) && sch.isConnected() );
			}
		}

		public void dispose()
		{
			super.dispose();
			if( sch != null ) {
				try {
//System.err.println( "TCPOSCTransmitter.closeChannel()" );
//new IOException( "TCPOSCTransmitter.closeChannel()" ).printStackTrace();
					sch.close();
//System.err.println( "... ok " );
				}
				catch( IOException e1 ) {
					e1.printStackTrace();
				}
				sch = null;
			}
		}

		public void send( OSCPacketCodec c, OSCPacket p, SocketAddress target )
		throws IOException
		{
			synchronized( sync ) {
				if( (target != null) && !target.equals( this.target )) throw new IllegalStateException( NetUtil.getResourceString( "errNotBoundToAddress" ) + target );

				send( c, p );
			}
		}

		public void send( OSCPacketCodec c, OSCPacket p )
		throws IOException
		{
			final int len;

			try {
				synchronized( sync ) {
//					if( sch == null ) throw new NotYetConnectedException();
					if( sch == null ) throw new IOException( NetUtil.getResourceString( "errChannelNotConnected" ));

					checkBuffer();
					byteBuf.clear();
					byteBuf.position( 4 );
					c.encode( p, byteBuf );
					len = byteBuf.position() - 4;
					byteBuf.flip();
					byteBuf.putInt( 0, len );

					if( dumpMode != kDumpOff ) {
						printStream.print( "s: " );
						if( (dumpMode & kDumpText) != 0 ) OSCPacket.printTextOn( printStream, p );
						if( (dumpMode & kDumpHex)  != 0 ) {
							OSCPacket.printHexOn( printStream, byteBuf );
							byteBuf.flip();
						}
					}

					sch.write( byteBuf );
				}
			}
			catch( BufferOverflowException e1 ) {
				throw new OSCException( OSCException.BUFFER,
					p instanceof OSCMessage ? ((OSCMessage) p).getName() : p.getClass().getName() );
			}
		}
	}
}


text:
@interface RegisterWorkerViewController : UIViewController<UITextFieldDelegate>

@end

redpajama_set_name: RedPajamaGithub


text:
// Copyright 2020 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.bazel.repository.downloader;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.ISO_8859_1;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.fail;

import com.google.auth.Credentials;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.authandtls.BasicHttpAuthenticationEncoder;
import com.google.devtools.build.lib.testutil.Scratch;
import com.google.devtools.build.lib.vfs.DigestHashFunction;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
import java.io.IOException;
import java.io.StringReader;
import java.net.URI;
import java.net.URL;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import net.starlark.java.syntax.Location;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Unit tests for {@link UrlRewriter} */
@RunWith(JUnit4.class)
public class UrlRewriterTest {

  @Test
  public void byDefaultTheUrlRewriterDoesNothing() throws Exception {
    UrlRewriter munger = new UrlRewriter(str -> {}, "/dev/null", new StringReader(""));

    List<URL> urls = ImmutableList.of(new URL("http://example.com"));
    ImmutableList<URL> amended =
        munger.amend(urls).stream().map(url -> url.url()).collect(toImmutableList());

    assertThat(amended).isEqualTo(urls);
  }

  @Test
  public void shouldBeAbleToBlockParticularHostsRegardlessOfScheme() throws Exception {
    String config = "block example.com";
    UrlRewriter munger = new UrlRewriter(str -> {}, "/dev/null", new StringReader(config));

    List<URL> urls =
        ImmutableList.of(
            new URL("http://example.com"),
            new URL("https://example.com"),
            new URL("http://localhost"));
    ImmutableList<URL> amended =
        munger.amend(urls).stream().map(url -> url.url()).collect(toImmutableList());

    assertThat(amended).containsExactly(new URL("http://localhost"));
  }

  @Test
  public void shouldAllowAUrlToBeRewritten() throws Exception {
    String config = "rewrite example.com/foo/(.*) mycorp.com/$1/foo";
    UrlRewriter munger = new UrlRewriter(str -> {}, "/dev/null", new StringReader(config));

    List<URL> urls = ImmutableList.of(new URL("https://example.com/foo/bar"));
    ImmutableList<URL> amended =
        munger.amend(urls).stream().map(url -> url.url()).collect(toImmutableList());

    assertThat(amended).containsExactly(new URL("https://mycorp.com/bar/foo"));
  }

  @Test
  public void rewritesCanExpandToMoreThanOneUrl() throws Exception {
    String config =
        "rewrite example.com/foo/(.*) mycorp.com/$1/somewhere\n"
            + "rewrite example.com/foo/(.*) mycorp.com/$1/elsewhere";
    UrlRewriter munger = new UrlRewriter(str -> {}, "/dev/null", new StringReader(config));

    List<URL> urls = ImmutableList.of(new URL("https://example.com/foo/bar"));
    ImmutableList<URL> amended =
        munger.amend(urls).stream().map(url -> url.url()).collect(toImmutableList());

    // There's no guarantee about the ordering of the rewrites
    assertThat(amended).contains(new URL("https://mycorp.com/bar/somewhere"));
    assertThat(amended).contains(new URL("https://mycorp.com/bar/elsewhere"));
  }

  @Test
  public void shouldBlockAllUrlsOtherThanSpecificOnes() throws Exception {
    String config = "" + "block *\n" + "allow example.com";

    UrlRewriter munger = new UrlRewriter(str -> {}, "/dev/null", new StringReader(config));

    List<URL> urls =
        ImmutableList.of(
            new URL("https://foo.com"),
            new URL("https://example.com/foo/bar"),
            new URL("https://subdomain.example.com/qux"));
    ImmutableList<URL> amended =
        munger.amend(urls).stream().map(url -> url.url()).collect(toImmutableList());

    assertThat(amended)
        .containsExactly(
            new URL("https://example.com/foo/bar"), new URL("https://subdomain.example.com/qux"));
  }

  @Test
  public void commentsArePrecededByTheHashCharacter() throws Exception {
    String config =
        ""
            + "# Block everything\n"
            + "block *\n"
            + "# But allow example.com\n"
            + "allow example.com";

    UrlRewriter munger = new UrlRewriter(str -> {}, "/dev/null", new StringReader(config));

    List<URL> urls = ImmutableList.of(new URL("https://foo.com"), new URL("https://example.com"));
    ImmutableList<URL> amended =
        munger.amend(urls).stream().map(url -> url.url()).collect(toImmutableList());

    assertThat(amended).containsExactly(new URL("https://example.com"));
  }

  @Test
  public void allowListAppliesToSubdomainsToo() throws Exception {
    String config = "" + "block *\n" + "allow example.com";

    UrlRewriter munger = new UrlRewriter(str -> {}, "/dev/null", new StringReader(config));

    ImmutableList<URL> amended =
        munger.amend(ImmutableList.of(new URL("https://subdomain.example.com"))).stream()
            .map(url -> url.url())
            .collect(toImmutableList());

    assertThat(amended).containsExactly(new URL("https://subdomain.example.com"));
  }

  @Test
  public void blockListAppliesToSubdomainsToo() throws Exception {
    String config = "block example.com";

    UrlRewriter munger = new UrlRewriter(str -> {}, "/dev/null", new StringReader(config));

    ImmutableList<URL> amended =
        munger.amend(ImmutableList.of(new URL("https://subdomain.example.com"))).stream()
            .map(url -> url.url())
            .collect(toImmutableList());

    assertThat(amended).isEmpty();
  }

  @Test
  public void emptyLinesAreFine() throws Exception {
    String config = "" + "\n" + "   \n" + "block *\n" + "\t  \n" + "allow example.com";

    UrlRewriter munger = new UrlRewriter(str -> {}, "/dev/null", new StringReader(config));

    ImmutableList<URL> amended =
        munger.amend(ImmutableList.of(new URL("https://subdomain.example.com"))).stream()
            .map(url -> url.url())
            .collect(toImmutableList());

    assertThat(amended).containsExactly(new URL("https://subdomain.example.com"));
  }

  @Test
  public void rewritingUrlsIsAppliedBeforeBlocking() throws Exception {
    String config = "" + "block bad.com\n" + "rewrite bad.com/foo/(.*) mycorp.com/$1";

    UrlRewriter munger = new UrlRewriter(str -> {}, "/dev/null", new StringReader(config));

    List<URL> amended =
        munger
            .amend(
                ImmutableList.of(
                    new URL("https://www.bad.com"), new URL("https://bad.com/foo/bar")))
            .stream()
            .map(url -> url.url())
            .collect(toImmutableList());

    assertThat(amended).containsExactly(new URL("https://mycorp.com/bar"));
  }

  @Test
  public void rewritingUrlsIsAppliedBeforeAllowing() throws Exception {
    String config =
        "" + "block *\n" + "allow mycorp.com\n" + "rewrite bad.com/foo/(.*) mycorp.com/$1";

    UrlRewriter munger = new UrlRewriter(str -> {}, "/dev/null", new StringReader(config));

    List<URL> amended =
        munger
            .amend(
                ImmutableList.of(
                    new URL("https://www.bad.com"), new URL("https://bad.com/foo/bar")))
            .stream()
            .map(url -> url.url())
            .collect(toImmutableList());

    assertThat(amended).containsExactly(new URL("https://mycorp.com/bar"));
  }

  @Test
  public void parseError() throws Exception {
    String config = "#comment\nhello";
    try {
      new UrlRewriterConfig("/some/file", new StringReader(config));
      fail();
    } catch (UrlRewriterParseException e) {
      assertThat(e.getLocation()).isEqualTo(Location.fromFileLineColumn("/some/file", 2, 0));
    }
  }

  @Test
  public void noAllBlockedMessage() throws Exception {
    String config = "";
    UrlRewriterConfig munger = new UrlRewriterConfig("/some/file", new StringReader(config));
    assertThat(munger.getAllBlockedMessage()).isNull();
  }

  @Test
  public void singleAllBlockedMessage() throws Exception {
    String config =
        "all_blocked_message I'm sorry Dave, I'm afraid I can't do that.\n" + "allow *\n";
    UrlRewriterConfig munger = new UrlRewriterConfig("/some/file", new StringReader(config));
    assertThat(munger.getAllBlockedMessage())
        .isEqualTo("I'm sorry Dave, I'm afraid I can't do that.");
  }

  @Test
  public void multipleAllBlockedMessage() throws Exception {
    String config = "all_blocked_message one\n" + "block *\n" + "all_blocked_message two\n";
    try {
      new UrlRewriterConfig("/some/file", new StringReader(config));
      fail();
    } catch (UrlRewriterParseException e) {
      assertThat(e.getLocation()).isEqualTo(Location.fromFileLineColumn("/some/file", 3, 0));
    }
  }

  @Test
  public void rewritingUrlsAllowsProtocolRewrite() throws Exception {
    String config =
        ""
            + "block *\n"
            + "allow mycorp.com\n"
            + "allow othercorp.com\n"
            + "rewrite bad.com/foo/(.*) http://mycorp.com/$1\n"
            + "rewrite bad.com/bar/(.*) https://othercorp.com/bar/$1\n";

    UrlRewriter munger = new UrlRewriter(str -> {}, "/dev/null", new StringReader(config));

    List<URL> amended =
        munger
            .amend(
                ImmutableList.of(
                    new URL("https://www.bad.com"),
                    new URL("https://bad.com/foo/bar"),
                    new URL("http://bad.com/bar/xyz")))
            .stream()
            .map(url -> url.url())
            .collect(toImmutableList());

    assertThat(amended)
        .containsExactly(
            new URL("http://mycorp.com/bar"), new URL("https://othercorp.com/bar/xyz"));
  }

  @Test
  public void rewritingUrlsWithAuthHeaders() throws Exception {
    String creds = "user:password";
    String firstNetrcCreds = "netrc_user_0:netrc_pw_0";
    String secondNetrcCreds = "netrc_user_1:netrc_pw_1";
    Credentials netrc =
        parseNetrc(
            "machine mycorp.com login netrc_user_0 password netrc_pw_0\n"
                + "machine myothercorp.com login netrc_user_1 password netrc_pw_1\n"
                + "machine no-override.com login netrc_user_2 password netrc_pw_2\n");
    String config =
        ""
            + "rewrite my.example.com/foo/(.*) "
            + creds
            + "@mycorp.com/foo/$1\n" // this cred should from download config file
            + "rewrite my.example.com/from_netrc/(.*) mycorp.com/from_netrc/$1\n" // this cred
            // should come
            // from netrc
            + "rewrite"
            + " my.example.com/from_other_netrc_entry/(.*)"
            + " myothercorp.com/from_netrc/$1\n" // this cred should come from netrc
            + "rewrite my.example.com/no_creds/(.*) myopencorp.com/no_creds/$1\n"; // should be
    // re-written,
    // but no auth
    // headers added

    UrlRewriter munger = new UrlRewriter(str -> {}, "/dev/null", new StringReader(config));

    ImmutableList<UrlRewriter.RewrittenURL> amended =
        munger.amend(
            ImmutableList.of(
                new URL("https://my.example.com/foo/bar"),
                new URL("https://my.example.com/from_netrc/bar"),
                new URL("https://my.example.com/from_other_netrc_entry/bar"),
                new URL("https://my.example.com/no_creds/bar"),
                new URL("https://should-not-be-overridden.com/")));
    Map<URI, Map<String, List<String>>> updatedAuthHeaders =
        munger.updateAuthHeaders(amended, ImmutableMap.of(), netrc);

    String expectedToken =
        "Basic " + Base64.getEncoder().encodeToString(creds.getBytes(ISO_8859_1));
    String expectedFirstNetrcToken =
        "Basic " + Base64.getEncoder().encodeToString(firstNetrcCreds.getBytes(ISO_8859_1));
    String expectedSecondNetrcToken =
        "Basic " + Base64.getEncoder().encodeToString(secondNetrcCreds.getBytes(ISO_8859_1));
    // only three URLs should have auth headers
    assertThat(updatedAuthHeaders)
        .containsExactly(
            new URI("https://user:password@mycorp.com/foo/bar"),
            ImmutableMap.of("Authorization", ImmutableList.of(expectedToken)),
            new URI("https://mycorp.com/from_netrc/bar"),
            ImmutableMap.of("Authorization", ImmutableList.of(expectedFirstNetrcToken)),
            new URI("https://myothercorp.com/from_netrc/bar"),
            ImmutableMap.of("Authorization", ImmutableList.of(expectedSecondNetrcToken)));
    // yet all four urls should be present
    assertThat(amended)
        .containsExactly(
            UrlRewriter.RewrittenURL.create(
                new URL("https://user:password@mycorp.com/foo/bar"), true),
            UrlRewriter.RewrittenURL.create(new URL("https://mycorp.com/from_netrc/bar"), true),
            UrlRewriter.RewrittenURL.create(
                new URL("https://myothercorp.com/from_netrc/bar"), true),
            UrlRewriter.RewrittenURL.create(new URL("https://myopencorp.com/no_creds/bar"), true),
            UrlRewriter.RewrittenURL.create(
                new URL("https://should-not-be-overridden.com/"), false));
  }

  @Test
  public void testNetrc_emptyEnv_shouldIgnore() throws Exception {
    ImmutableMap<String, String> clientEnv = ImmutableMap.of();
    Path workingDir = new InMemoryFileSystem(DigestHashFunction.SHA256).getPath("/workdir");

    Credentials credentials = UrlRewriter.newCredentialsFromNetrc(clientEnv, workingDir);

    assertThat(credentials).isNull();
  }

  @Test
  public void testNetrc_netrcNotExist_shouldIgnore() throws Exception {
    String home = "/home/foo";
    ImmutableMap<String, String> clientEnv = ImmutableMap.of("HOME", home, "USERPROFILE", home);
    Path workingDir = new InMemoryFileSystem(DigestHashFunction.SHA256).getPath("/workdir");

    Credentials credentials = UrlRewriter.newCredentialsFromNetrc(clientEnv, workingDir);

    assertThat(credentials).isNull();
  }

  @Test
  public void testNetrc_relativeNetrc_shouldUse() throws Exception {
    FileSystem fileSystem = new InMemoryFileSystem(DigestHashFunction.SHA256);
    Path workingDir = fileSystem.getPath("/workdir");
    Scratch scratch = new Scratch(fileSystem);
    scratch.file("/workdir/foo/.netrc", "machine foo.example.org login foouser password foopass");
    ImmutableMap<String, String> clientEnv = ImmutableMap.of("NETRC", "./foo/.netrc");

    Credentials credentials = UrlRewriter.newCredentialsFromNetrc(clientEnv, workingDir);

    assertRequestMetadata(
        credentials.getRequestMetadata(URI.create("https://foo.example.org")),
        "foouser",
        "foopass");
  }

  @Test
  public void testNetrc_relativeNetrc_shouldIgnoreWhenNotExist() throws Exception {
    FileSystem fileSystem = new InMemoryFileSystem(DigestHashFunction.SHA256);
    Path workingDir = fileSystem.getPath("/workdir");
    ImmutableMap<String, String> clientEnv = ImmutableMap.of("NETRC", "./foo/.netrc");

    Credentials credentials = UrlRewriter.newCredentialsFromNetrc(clientEnv, workingDir);

    assertThat(credentials).isNull();
  }

  @Test
  public void testNetrc_netrcExist_shouldUse() throws Exception {
    Credentials credentials = parseNetrc("machine foo.example.org login foouser password foopass");

    assertThat(credentials).isNotNull();
    assertRequestMetadata(
        credentials.getRequestMetadata(URI.create("https://foo.example.org")),
        "foouser",
        "foopass");
  }

  @Test
  public void testNetrc_netrcExist_cant_parse() throws Exception {
    String home = "/home/foo";
    ImmutableMap<String, String> clientEnv = ImmutableMap.of("HOME", home, "USERPROFILE", home);
    FileSystem fileSystem = new InMemoryFileSystem(DigestHashFunction.SHA256);
    Scratch scratch = new Scratch(fileSystem);
    scratch.file(home + "/.netrc", "mach foo.example.org log foouser password foopass");

    try {
      UrlRewriter.newCredentialsFromNetrc(clientEnv, fileSystem.getPath("/workdir"));
      fail();
    } catch (UrlRewriterParseException e) {
      assertThat(e.getLocation()).isEqualTo(Location.fromFileLineColumn("/home/foo/.netrc", 0, 0));
    }
  }

  private static Credentials parseNetrc(String content)
      throws IOException, UrlRewriterParseException {
    String home = "/home/foo";
    ImmutableMap<String, String> clientEnv = ImmutableMap.of("HOME", home, "USERPROFILE", home);
    FileSystem fileSystem = new InMemoryFileSystem(DigestHashFunction.SHA256);
    Path workingDir = fileSystem.getPath("/workdir");
    Scratch scratch = new Scratch(fileSystem);
    scratch.file(home + "/.netrc", content);

    return UrlRewriter.newCredentialsFromNetrc(clientEnv, workingDir);
  }

  private static void assertRequestMetadata(
      Map<String, List<String>> requestMetadata, String username, String password) {
    assertThat(requestMetadata.keySet()).containsExactly("Authorization");
    assertThat(Iterables.getOnlyElement(requestMetadata.values()))
        .containsExactly(BasicHttpAuthenticationEncoder.encode(username, password, UTF_8));
  }
}


text:
using MetaDslx.CodeAnalysis.Symbols;
using Microsoft.CodeAnalysis;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Text;

namespace MetaDslx.CodeAnalysis.Binding.Binders
{
    public class PropertyBinder : Binder
    {
        private readonly string _propertyName;
        private readonly Optional<object> _propertyValueOpt;
        private ImmutableArray<object> _lazyValues;
        private SymbolPropertyOwner _owner;
        private Type _ownerType;

        public PropertyBinder(Binder next, string propertyName, Optional<object> propertyValueOpt, SymbolPropertyOwner owner, Type ownerType)
            : base(next)
        {
            _propertyName = propertyName;
            _propertyValueOpt = propertyValueOpt;
            _owner = owner;
            _ownerType = ownerType;
            if (_propertyValueOpt.HasValue)
            {
                _lazyValues = ImmutableArray.Create(_propertyValueOpt.Value);
            }
            else
            {
                _lazyValues = default(ImmutableArray<object>);
            }
        }

        public override DeclaredSymbol GetDeclarationSymbol()
        {
            switch (_owner)
            {
                case SymbolPropertyOwner.CurrentSymbol:
                    return this.GetParentDeclaredSymbol();
                case SymbolPropertyOwner.CurrentScope:
                    return this.GetParentDeclaredScope();
                case SymbolPropertyOwner.AncestorSymbol:
                    return this.GetAncestorDeclaredSymbol();
                case SymbolPropertyOwner.AncestorScope:
                    return this.GetAncestorDeclaredScope();
                default:
                    throw new NotImplementedException();
            }
        }

        private DeclaredSymbol GetParentDeclaredSymbol()
        {
            var current = this.Next;
            while (current != null)
            {
                if (current is SymbolDefBinder symbolDefBinder)
                {
                    var result = symbolDefBinder.LastDeclaredSymbol;
                    if (result != null) return result;
                    else break;
                }
                current = current.Next;
            }
            return (NamespaceOrTypeSymbol)this.Compilation.CreateErrorNamespaceSymbol(this.Compilation.GlobalNamespace, string.Empty);
        }

        private DeclaredSymbol GetParentDeclaredScope()
        {
            var current = this.Next;
            while (current != null)
            {
                if (current is ScopeBinder scopeBinder)
                {
                    var result = scopeBinder.DeclaredSymbol;
                    if (result != null) return result;
                    else break;
                }
                current = current.Next;
            }
            return (NamespaceOrTypeSymbol)this.Compilation.CreateErrorNamespaceSymbol(this.Compilation.GlobalNamespace, string.Empty);
        }

        private DeclaredSymbol GetAncestorDeclaredSymbol()
        {
            var current = this.Next;
            while (current != null)
            {
                if (current is SymbolDefBinder symbolDefBinder)
                {
                    var result = symbolDefBinder.LastDeclaredSymbol;
                    if (result != null && (_ownerType == null || _ownerType.IsAssignableFrom(result.GetType())))
                    {
                        return result;
                    }
                }
                current = current.Next;
            }
            return (NamespaceOrTypeSymbol)this.Compilation.CreateErrorNamespaceSymbol(this.Compilation.GlobalNamespace, string.Empty);
        }

        private DeclaredSymbol GetAncestorDeclaredScope()
        {
            var current = this.Next;
            while (current != null)
            {
                if (current is ScopeBinder scopeBinder)
                {
                    var result = scopeBinder.DeclaredSymbol;
                    if (result != null && (_ownerType == null || _ownerType.IsAssignableFrom(result.GetType())))
                    {
                        return result;
                    }
                }
                current = current.Next;
            }
            return (NamespaceOrTypeSymbol)this.Compilation.CreateErrorNamespaceSymbol(this.Compilation.GlobalNamespace, string.Empty);
        }
    }
}


text:
OLM is composed of two Operators: the OLM Operator and the Catalog Operator.

Each of these Operators is responsible for managing the CRDs that are the basis for the OLM framework:

| Resource                 | Short Name | Owner   | Description                                                                                |
|--------------------------|------------|---------|--------------------------------------------------------------------------------------------|
| ClusterServiceVersion | csv        | OLM     | application metadata: name, version, icon, required resources, installation, etc...        |
| InstallPlan           | ip         | Catalog | calculated list of resources to be created in order to automatically install/upgrade a CSV |
| CatalogSource         | catsrc         | Catalog | a repository of CSVs, CRDs, and packages that define an application                        |
| Subscription          | sub        | Catalog | used to keep CSVs up to date by tracking a channel in a package                            |
| OperatorGroup         | og     | OLM     | used to group multiple namespaces and prepare for use by an operator                     |

Each of these Operators are also responsible for creating resources:

| Operator | Creatable Resources        |
|----------|----------------------------|
| OLM      | Deployment                 |
| OLM      | Service Account            |
| OLM      | (Cluster)Roles             |
| OLM      | (Cluster)RoleBindings      |
| Catalog  | Custom Resource Definition |
| Catalog  | ClusterServiceVersion      |

## What is a ClusterServiceVersion

ClusterServiceVersion combines metadata and runtime information about a service that allows OLM to manage it.

ClusterServiceVersion:

- Metadata (name, description, version, links, labels, icon, etc)
- Install strategy
  - Type: Deployment
    - Set of service accounts / required permissions
    - Set of deployments

- CRDs
  - Type
  - Owned - managed by this service
  - Required - must exist in the cluster for this service to run
  - Resources - a list of k8s resources that the Operator interacts with
  - Descriptors - annotate CRD spec and status fields to provide semantic information

## OLM Operator

The OLM Operator is responsible for installing applications defined by a `ClusterServiceVersion` resources once the required resources specified in the CSV are present in the cluster (the job of the Cluster Operator). This may be as simple as setting up a single `Deployment` resulting in an operator's pod becoming available. The OLM Operator is not concerned with the creation of the underlying resources. If this is not done manually, the Catalog Operator can help provide resolution of these needs.

This separation of concerns enables users incremental buy-in of the OLM framework components. Users can choose to manually create these resources, or define an InstallPlan for the Catalog Operator or allow the Catalog Operator to develop and implement the InstallPlan. An operator creator does not need to learn about the full operator package system before seeing a working operator.

While the OLM Operator is often configured to watch all namespaces, it can also be operated alongside other OLM Operators so long as they all manage separate namespaces defined by `OperatorGroups`.

### ClusterServiceVersion Control Loop

```
           +------------------------------------------------------+
           |                                                      |
           |                                      +--> Succeeded -+
           v                                      |               |
None --> Pending --> InstallReady --> Installing -|               |
           ^                                       +--> Failed <--+
           |                                              |
           +----------------------------------------------+
\                                                                 /
 +---------------------------------------------------------------+
    |
    v
Replacing --> Deleting
```
*Note: The transition to replacing happens out-of-band when the controller detects a new CSV that replaces the current one.*

| Phase      | Description                                                                                |
|------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| None       | initial phase, once seen by the Operator, it is immediately transitioned to `Pending`                                                                                |
| Pending    | requirements in the CSV are not met, once they are this phase transitions to `InstallReady`                                                                                |
| InstallReady | all requirements in the CSV are present, the Operator will begin executing the install strategy                                                                                |
| Installing | the install strategy is being executed and resources are being created, but not all components are reporting as ready                                                                                |
| Succeeded  | the execution of the Install Strategy was successful; if requirements disappear, or an APIService cert needs to be rotated this may transition back to `Pending`; if an installed component disappears this may transition to `Failed`|
| Failed     | upon failed execution of the Install Strategy, or an installed component disappears the CSV transitions to this phase; if the component can be recreated by OLM, this may transition to `Pending`                                     |
| Replacing  | a newer CSV that replaces this one has been discovered in the cluster. This status means the CSV is marked for GC                                                                                |
| Deleting   | the GC loop has determined this CSV is safe to delete from the cluster. It will disappear soon.                                                                                |
> Note: In order to transition, a CSV must first be an active member of an OperatorGroup

## Catalog Operator

The Catalog Operator is responsible for monitoring `Subscriptions`, `CatalogSources` and the catalogs themselves. When it finds a new or changed `Subscription`, it builds out the subscribed Operator. When it finds a new or changed CatalogSource it builds out the required catalog, if appropriate, and begins regular monitoring of the package in the catalog. The packages in the catalog will include various `ClusterServiceVersions`, `CustomResourceDefinitions` and a channel list for each package. A catalog has packages. A package has channels and CSVs. A Channels identifies a specific CSV. The CSVs identify specific CRDs.

A user wanting a specific operator creates a `Subscription` which identifies a catalog, operator and channel within that operator. The Catalog Operator then receives that information and queries the catalog for the latest version of the channel requested. Then it looks up the appropriate `ClusterServiceVersion` identified by the channel and turns that into an `InstallPlan`. When updates are found in the catalog for the channel, a similar process occurs resulting in a new `InstallPlan`. (Users can also create an InstallPlan resource directly, containing the names of the desired ClusterServiceVersions and an approval strategy.)

When the Catalog Operator find a new `InstallPlan`, even though it likely created it, it will create an "execution plan" and embed that into the `InstallPlan` to create all of the required resources. Once approved, whether manually or automatically, the Catalog Operator will implement its portion of the the execution plan, satisfying the underlying expectations of the OLM Operator.

The OLM Operator will then pickup the installation and carry it through to completion of everything required in the identified CSV.

### InstallPlan Control Loop

```
None --> Planning +------>------->------> Installing +---> Complete
                  |                       ^          |
                  v                       |          v
                  +--> RequiresApproval --+          Failed
```

| Phase            | Description                                                                                |
|------------------|------------------------------------------------------------------------------------------------|
| None             | initial phase, once seen by the Operator, it is immediately transitioned to `Planning`         |
| Planning         | dependencies between resources are being resolved, to be stored in the InstallPlan `Status`    |
| RequiresApproval | occurs when using manual approval, will not transition phase until `approved` field is true    |
| Installing       | waiting for reconciliation of required resource(OG/SA etc), or resolved resources in the
                     InstallPlan `Status` block are being created                                                   |
| Complete         | all resolved resources in the `Status` block exist                                             |
| Failed           | occurs when resources fail to install or when bundle unpacking fails                           |

### Subscription Control Loop

```
None --> UpgradeAvailable --> UpgradePending --> AtLatestKnown -+
         ^                                   |                  |
         |                                   v                  v
         +----------<---------------<--------+---------<--------+
```

| Phase            | Description                                                                                |
|------------------|---------------------------------------------------------------------------------------------------------------|
| None             | initial phase, once seen by the Operator, it is immediately transitioned to `UpgradeAvailable`                |
| UpgradeAvailable | catalog contains a CSV which replaces the `status.installedCSV`, but no `InstallPlan` has been created yet |
| UpgradePending   | `InstallPlan` has been created (referenced in `status.installplan`) to install a new CSV                   |
| AtLatestKnown    | `status.installedCSV` matches the latest available CSV in catalog                                             |

## Catalog (Registry) Design

The Catalog Registry stores CSVs and CRDs for creation in a cluster, and stores metadata about packages and channels.

A package manifest is an entry in the catalog registry that associates a package identity with sets of ClusterServiceVersions. Within a package, channels point to a particular CSV. Because CSVs explicitly reference the CSV that they replace, a package manifest provides the catalog Operator all of the information that is required to update a CSV to the latest version in a channel (stepping through each intermediate version).

```
Package {name}
  |
  +-- Channel {name} --> CSV {version} (--> CSV {version - 1} --> ...)
  |
  +-- Channel {name} --> CSV {version}
  |
  +-- Channel {name} --> CSV {version}
```


text:
CF-NetCDF as reference data model for VW
========================================

Intro
-----

In this project we want to collect mutually relevant data from WC-WAVE
researchers that will be discoverable as a first step to being usable by
other WC-WAVE researchers for whatever model they choose. In short, this
necessitated the choice of a data model. The NetCDF data model itself is
sensible and implemented in common programming languages, but it also offers
web-based tools (a RESTful API?) for selecting and downloading only subsets of
data on disk. Since NetCDF knows how to slice by loading selectively from disk,
the user does not have to load everything into memory before slicing.

NetCDF is intended as a self-describing data format. In other words, it contains
its own metadata. The Climate and Forecast (CF) conventions provide a common
guiding framework for writing this metadata, so that other any researcher
following the CF standard can easily share or process thiers or others' data
with a common set of tools like
`cfplot <http://www.met.reading.ac.uk/~andy/cfplot_sphinx/_build/html/>`_.
CF has the canonical documentation on its standard on its organization page:
`http://cfconventions.org/documents.html
<http://cfconventions.org/documents.html>`_.

Although necessary for creating a cutting-edge toolset for hydrological
modeling, all this infrastructure comes with some conceptual overhead. Here is
some background on the CF-NetCDF format.

Resources for Understanding NetCDF(-python)
-------------------------------------------

Because Python seems to be the most widely used language in our project, we will
be using and supporting the `NetCDF-python API <https://github.com/Unidata/netcdf4-python>`_.

Probably the best way to quickly get a feel for NetCDF, model and Python
interface, is to see these two python notebooks by the creator of the
NetCDF-python API: `reading_netCDF.ipynb <http://nbviewer.ipython.org/github/Unidata/netcdf4-python/blob/master/examples/reading_netCDF.ipynb>`_
and
`writing_netCDF.ipynb <http://nbviewer.ipython.org/github/Unidata/netcdf4-python/blob/master/examples/writing_netCDF.ipynb>`_.

Also, have a look at the basic data model for NetCDF files:

.. figure:: figures/nc-classic-uml.png
   :alt: Classic Data Model

   Classic Data Model

Taken from `UNIDATA
site <http://www.unidata.ucar.edu/software/netcdf/docs/html_tutorial/nc-classic-uml.png>`_.
There are some important things to note so we are speaking the same language.
First, a ``Dataset`` is a *container* for ``dimensions``, ``variables``, and
``attributes``, themselves containers for their data and metadata about
themselves or the ``Dataset``. The next part will require the basic understanding
gained from working through the above ipynb's.

Example 1: Create a NetCDF of temperature on a grid
---------------------------------------------------

In overly simple terms we use NetCDF to represent data as a function of some
coordinates, like a grid of longitude and latitude values. This example will
show how we create a NetCDF of air temperatures on a 3x4 grid.

First, in order to follow the CF standard for our variable name, we need to
check what we should use at the `web tool for CF standard names
<http://cfconventions.org/Data/cf-standard-names/27/build/cf-standard-name-table.html>`_.
Luckily this one is easy, the standard name is `air_temperature`, and actually
the standard name goes in the metadata about the variable. We just call the
python variable ``temp``. Some of the code is taken directly from the
`writing_netCDF.ipynb <http://nbviewer.ipython.org/github/Unidata/netcdf4-python/blob/master/examples/writing_netCDF.ipynb>`_.
example from the netCDF-python documentation.

To represent the "x" and "y" latitude and longitude coordinates, we consult
Chapter 4 of the CF standard, `Coordinate types <http://cfconventions.org/Data/cf-conventions/cf-conventions-1.7/build/ch04.html>`_.
We will format and give attributes for our coordinate variables, latitude and
longitude, according to the instructions there.

The process of creating a new .nc dataset is:

#. Create an empty Dataset object
#. Create the 'dimensions', e.g. lat, lon, altitude, time
#. Create the variables. Each of the dimensions has an associated variable
   where the actual values of the dimension are stored. Here we also attach
   weather data like temperature, snow water equivalent, solar radiation, etc.
#. Add attributes, which are just additional metadata. There is global- and
   variable-scope metadata. See CF Conventions `Section 2.6: Attributes
   <http://cfconventions.org/Data/cf-conventions/cf-conventions-1.7/build/ch02s06.html>`_
   for the reference documentation.

Here's the code for creating this grid of temperature data:

.. code-block:: python

    from __future__ import print_function
    import netCDF4      # Note: python is case-sensitive!
    import numpy as np  # numpy provides our data types; see var init below

    # initialize new dataset
    ncfile = netCDF4.Dataset('new.nc', mode='w', format='NETCDF4_CLASSIC')

    # initialize dimensions
    lat_dim = ncfile.createDimension('lon', 3)     # longitude axis
    lat_dim = ncfile.createDimension('lat', 4)     # latitude axis

    # Define two variables with the same names as dimensions,
    # a conventional way to define "coordinate variables".
    lat = ncfile.createVariable('lat', np.float32, ('lat',))
    lat.units = 'degrees_north'
    lat.long_name = 'latitude'

    lon = ncfile.createVariable('lon', np.float32, ('lon',))
    lon.units = 'degrees_east'
    lon.long_name = 'longitude'

    # Temperature is a function of latitude and longitude
    temp = ncfile.createVariable('temp', np.float64, ('lat','lon'))
    temp.units = 'K'  # degrees Kelvin
    temp.standard_name = 'air_temperature'  # this is a CF standard name

    # Write latitudes, longitudes.
    nlats = len(lat_dim)
    nlons = len(lon_dim)
    # Note: the ":" is necessary in these "write" statements
    lat[:] = -90. + (180./nlats)*np.arange(nlats) # south pole to north pole
    lon[:] = (180./nlats)*np.arange(nlons) # Greenwich meridian eastward

    # populate temperature ndarray with reasonable earth temperatures
    temp_arr = np.random.uniform(low=280, high=330, size=(nlats,nlons))
    temp[:,:] = temp_arr

    # add attributes, all global; see CF standards
    ncfile.title = 'My model data'
    ncfile.institution = 'Idaho State University'
    ncfile.source = 'Weather Stations in Reynolds Creek Watershed'
    ncfile.history = 'Existed since 1990, first time in public domain'

    # to save the file to disk, close the `ncfile` object
    ncfile.close()

To confirm that this worked, check the output of ``ncdump`` at the command line.

.. code-block:: bash

    ncdump new.nc

You should see this, but with different random ``data``:

.. code-block:: cdl

    netcdf new {
    dimensions:
            lon = 3 ;
            lat = 4 ;
    variables:
            float lat(lat) ;
                    lat:units = "degrees_north" ;
                    lat:long_name = "latitude" ;
            float lon(lon) ;
                    lon:units = "degrees_east" ;
                    lon:long_name = "longitude" ;
            double temp(lat, lon) ;
                    temp:units = "K" ;
                    temp:standard_name = "air_temperature" ;

    // global attributes:
                    :title = "My model data" ;
                    :institution = "Idaho State University" ;
                    :source = "Weather Stations in Reynolds Creek Watershed" ;
                    :history = "Existed since 1990, first time in public domain" ;
    data:

     lat = -90, -45, 0, 45 ;

     lon = 0, 45, 90 ;

     temp =
      303.51644518952, 329.87896020043, 320.682946298552,
      282.647054412333, 294.753235738639, 297.738184716573,
      290.698305690645, 321.484896481591, 303.564564474415,
      304.710075475009, 321.517749128517, 324.796144202603 ;
    }

Example 2: Create a CF-formatted NetCDF of temperature at weather stations
------------------------------------------------------------------------

Consider the following situation: You have
weather stations named ``s1``, ``s2``, and ``s3`` recording the temperature at
three-dimensional points in space (x,y,z), which correspond to a longitude,
latitude, and altitutde. Each station records temperature every fifteen
minutes. The data has been processed so that the all four measurements taken
within an hour are averaged, so our temperature is really *mean temperature*,
but in most spots, we'll just call it ``temp`` for short. Here is our tabular
data:

==============  =======  ===========
station name    time     temp
==============  =======  ===========
s1              0        301.4
s2              0        298.0
s3              0        310.2
s1              1        300.4
s2              1        293.0
s3              1        306.2
s1              2        302.4
s2              2        288.0
s3              2        308.1
==============  =======  ===========

This time, our NetCDF dimensions are ``station name`` and ``time`` instead of
``lat`` and ``lon``. Then in our CDL our dimension declaration is

.. code-block:: cdl

    dimensions:
            time = UNLIMITED;
            station = 3;
            name_strlen = 2; // `s1` has two characters

By declaring ``time`` as ``UNLIMITED``, we allow for future measurements to be
appended to the Dataset.

We also have this tabular data about the stations:

==============  =======  ========  ======
station name    lat      lon       alt
==============  =======  ========  ======
s1              49.2     -115.4    1004
s2              49.4     -114.0    1025
s3              50.1     -116.2    923
==============  =======  ========  ======

So although lat, lon, and alt won't be "dimensions", they will be included as
"variables". We will consider them functions of "station name", each represented
in the CDL as

.. code-block:: cdl

    variables:
            char station_name(station):
                    station_name:long_name = "station name";
                    station_name:cf_role = "timeseries_id";
            float lat(station) ;
                    lat:long_name = "station latitude" ;
                    lat:standard_name = "latitude" ;
                    lat:units = "degrees_north" ;
            float lon(station) ;
                    lon:long_name = "station_longitude" ;
                    lon:standard_name = "longitude" ;
                    lon:units = "degrees_east" ;
            float alt(station) ;
                    alt:long_name = "vertical distance above the surface";
                    alt:standard_name = "height";
                    alt:units = "m";
                    alt:positive = "up";
                    alt:axis = "Z";

our temperature variable is a function of station and time:

.. code-block:: cdl

    variables:
            ...
            double time(time);
                    time:standard_name = "time";
                    time:long_name = "time of measurement"
                    time:units = "hours since 2005-10-01 00:00:00"
            float temp(time, station)
                    temp:standard_name = "air_temperature";
                    temp:units = "K";
                    temp:_FillValue = -999.9;

Build the dataset in python
```````````````````````````

We can consult the examples in the CF Conventions Manual in `Appendix H <http://cfconventions.org/Data/cf-conventions/cf-conventions-1.7/build/aph.html>`_ for guidance. We will essentially implement
`H2.1 <http://cfconventions.org/Data/cf-conventions/cf-conventions-1.7/build/aphs02.html>`_
but following the instructions from `the Write NetCDF ipynb <http://nbviewer.ipython.org/github/Unidata/unidata-python-workshop/blob/master/writing_netCDF.ipynb>`_
used before. Since we're using the classic data model, our assignments are in
the python procedure are in slightly different order.

.. code-block:: python

    from netCDF4 import Dataset
    import numpy as np
    import pandas as pd

    ncfile = Dataset('pygen_station_data.nc', mode='w', format='NETCDF4')

    # `None` stands for UNLIMITED here
    time_dim = ncfile.createDimension('time', None)
    station_dim = ncfile.createDimension('station', 3)

    station = ncfile.createVariable('station', str, ('station',))
    station.long_name = "station name"
    station.cf_role = "timeseries_id"

    time = ncfile.createVariable('time', np.float64, ('time',))
    time.units = 'hours since 2015-10-01 00:00:00'
    time.long_name = 'time'

    # lon, lat, altitude
    lon = ncfile.createVariable('lon', np.float32, ('station',))
    lon.standard_name = 'longitude'
    lon.long_name = 'station longitude'
    lon.units = 'degrees_east'

    lat = ncfile.createVariable('lat', np.float32, ('station',))
    lat.standard_name = 'latitude'
    lat.long_name = 'latitude'
    lat.units = 'degrees_north'

    alt = ncfile.createVariable('alt', np.float32, ('station',))
    alt.standard_name = 'height'
    alt.long_name = 'vertical distance above the surface'
    alt.units = 'm'
    alt.positive = 'up'
    alt.axis = 'Z'

    # temperature
    temp = ncfile.createVariable('temp', np.float32, ('time', 'station'),
                                 fill_value=-999.99)
    temp.units = 'K'
    temp.standard_name = 'air_temperature'

We have our tabular data that has the station information in
`examples/station_info.csv <https://github.com/tri-state-epscor/vw-doc/blob/master/examples/station_info.csv>`_ and the "weather" info (really just temperature)
in `examples/station_weather.csv <https://github.com/tri-state-epscor/vw-doc/blob/master/examples/station_weather.csv>`_. We'll use `read_csv <http://pandas.pydata.org/pandas-docs/dev/io.html#io-read-csv-table>`_
from the `pandas <http://pandas.pydata.org/>`_ data analysis library. We'll
read those files in and use the data stored in them to finish creating our
NetCDF version of the weather station data.

.. code-block:: python

    import pandas as pd
    import numpy as np

    station_info = pd.read_csv('examples/station_info.csv')
    station_weather = pd.read_csv('examples/station_weather.csv')

    station[:] = station_info.station_name
    time[:] = station_info.time

    lon[:] = station_info.lon
    lat[:] = station_info.lat
    alt[:] = station_info.alt

    station_weather.sort(['time', 'station_name'], inplace=True)

    temp_array = np.reshape(station_weather.time, (len(time),len(station)))

    temp[:,:] = temp_array

    ncfile.close()

The two blocks of python code in this example can be found in
`example/make_station_data.py <https://github.com/tri-state-epscor/vw-doc/blob/master/examples/make_station_data.py>`_. Run that example from the ``examples``
directory

.. code-block:: bash

    cd examples/ && python make_station_data.py

which will create a new file, ``pygen_station_data.nc``.

Confirm success
```````````````

If you haven't already,
get the NetCDF Operators package, `NCO <http://nco.sourceforge.net/>`_. It has
some nice tools, one of which will help us confirm that we have loaded the
NetCDF ``temp`` variable correctly. Using the `ncks
<http://nco.sourceforge.net/nco.html#ncks-netCDF-Kitchen-Sink>`_ utility (NetCDF
Kitchen Sink, you'll see why) we print a lot of info about the file. The
important part comes near the bottom

.. code-block:: bash

    ncks pygen_station_data.py

.. code-block:: cdl

    ...
    time[0]=0 station[0]=s1 temp[0]=301.4 K
    time[0]=0 station[1]=s2 temp[1]=298 K
    time[0]=0 station[2]=s3 temp[2]=310.2 K
    time[1]=1 station[0]=s1 temp[3]=300.4 K
    time[1]=1 station[1]=s2 temp[4]=293 K
    time[1]=1 station[2]=s3 temp[5]=306.2 K
    time[2]=2 station[0]=s1 temp[6]=302.4 K
    time[2]=2 station[1]=s2 temp[7]=288 K
    time[2]=2 station[2]=s3 temp[8]=308.1 K
    ...

We know we're good because this matches ``weather_stations.csv``.

Common data form Description Language (CDL)
-------------------------------------------

The Common data format Description Language is a plain-text, fail-safe way to
create NetCDF datasets. Once you write out the description of the data, you
can run ``ncgen`` (`extended documentation <https://www.unidata.ucar.edu/software/netcdf/docs/netcdf/ncgen.html#ncgen>`_
`manpage documentation <http://www.unidata.ucar.edu/software/netcdf/old_docs/docs_3_6_0/ncgen-man-1.html>`_)
to create a NetCDF file from a CDL file. This will check your syntax and
initialize a file for you. Here are a few resources for CDL:

* `NetCDF Workshop 2010 page on CDL <https://www.unidata.ucar.edu/software/netcdf/workshops/2010/utilities/CDL.html>`_
* `CDL Syntax <https://www.unidata.ucar.edu/software/netcdf/docs/netcdf/CDL-Syntax.html>`_

Here's how we could do the first example using just CDL files and ``ncgen``.
There is a CDL file in the `example <https://github.com/tri-state-epscor/vw-doc/tree/master/examples>`_
directory called ``weather_stations.cdl`` that defines weather station data
from Example 2.  To build an empty NetCDF file we could insert data into, call

.. code-block:: bash

    ncgen -o weather_stations.nc weather_stations.cdl

and we'd have a new NetCDF file ``weather_stations.nc`` with an all-empty data
section and identical dimension and variable sections.


text:
package eu.chargetime.ocpp.model.core;

/** Accepted values used with {@link SampledValue}. */
public enum Location {
  Body,
  Cable,
  EV,
  Inlet,
  Outlet
}


text:
using System;

    class TriangleSurfaceByTwoSidesAndAnAngle
    {
    static void Main()
    {
        double sideA = double.Parse(Console.ReadLine());
        double sideB = double.Parse(Console.ReadLine());
        double angleAB = double.Parse(Console.ReadLine());

        double area;

        area = SidesAngleTriangleArea(sideA, sideB, angleAB);

        Console.WriteLine("{0:F2}", area);
    }

    public static double SidesAngleTriangleArea(double sideA, double sideB, double angleAB)
    {
        return (sideA * sideB * Math.Sin(angleAB * Math.PI / 180)) / 2;
    }

}


text:
#ifndef ART_RUNTIME_GC_REFERENCE_QUEUE_H_
#define ART_RUNTIME_GC_REFERENCE_QUEUE_H_

#include <iosfwd>
#include <string>
#include <vector>

#include "atomic.h"
#include "base/timing_logger.h"
#include "globals.h"
#include "jni.h"
#include "object_callbacks.h"
#include "offsets.h"
#include "thread_pool.h"

namespace art {
namespace mirror {
class Reference;
}  // namespace mirror

namespace gc {

class Heap;

// Used to temporarily store java.lang.ref.Reference(s) during GC and prior to queueing on the
// appropriate java.lang.ref.ReferenceQueue. The linked list is maintained in the
// java.lang.ref.Reference objects.
class ReferenceQueue {
 public:
  explicit ReferenceQueue(Mutex* lock);

  // Enqueue a reference if is not already enqueued. Thread safe to call from multiple threads
  // since it uses a lock to avoid a race between checking for the references presence and adding
  // it.
  void AtomicEnqueueIfNotEnqueued(Thread* self, mirror::Reference* ref)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) LOCKS_EXCLUDED(lock_);

  // Enqueue a reference, unlike EnqueuePendingReference, enqueue reference checks that the
  // reference IsEnqueueable. Not thread safe, used when mutators are paused to minimize lock
  // overhead.
  void EnqueueReference(mirror::Reference* ref) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);

  // Enqueue a reference without checking that it is enqueable.
  void EnqueuePendingReference(mirror::Reference* ref) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);

  // Dequeue the first reference (returns list_).
  mirror::Reference* DequeuePendingReference() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);

  // Enqueues finalizer references with white referents.  White referents are blackened, moved to
  // the zombie field, and the referent field is cleared.
  void EnqueueFinalizerReferences(ReferenceQueue* cleared_references,
                                  IsHeapReferenceMarkedCallback* is_marked_callback,
                                  MarkObjectCallback* mark_object_callback, void* arg)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);

  // Walks the reference list marking any references subject to the reference clearing policy.
  // References with a black referent are removed from the list.  References with white referents
  // biased toward saving are blackened and also removed from the list.
  void ForwardSoftReferences(IsHeapReferenceMarkedCallback* preserve_callback, void* arg)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);

  // Unlink the reference list clearing references objects with white referents. Cleared references
  // registered to a reference queue are scheduled for appending by the heap worker thread.
  void ClearWhiteReferences(ReferenceQueue* cleared_references,
                            IsHeapReferenceMarkedCallback* is_marked_callback, void* arg)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);

  void Dump(std::ostream& os) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
  size_t GetLength() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);

  bool IsEmpty() const {
    return list_ == nullptr;
  }
  void Clear() {
    list_ = nullptr;
  }
  mirror::Reference* GetList() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    return list_;
  }

  // Visits list_, currently only used for the mark compact GC.
  void UpdateRoots(IsMarkedCallback* callback, void* arg)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);

 private:
  // Lock, used for parallel GC reference enqueuing. It allows for multiple threads simultaneously
  // calling AtomicEnqueueIfNotEnqueued.
  Mutex* const lock_;
  // The actual reference list. Only a root for the mark compact GC since it will be null for other
  // GC types.
  mirror::Reference* list_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(ReferenceQueue);
};

}  // namespace gc
}  // namespace art

#endif  // ART_RUNTIME_GC_REFERENCE_QUEUE_H_


text:
class CriteriaFactory {

    makeCreateCriteria(req, modelName) {

        let criteria;
        var params = req.body;
        switch (modelName) {
            case "User":
            case "Subscriber":
                criteria = this.byEmail(params.email);
                break;
            case "List":
            case "Account":
                criteria = this.byName(params.name);
                break;
        }

        // Add account id, if set by authentication
        if (req.user && req.user.accountId)
            criteria.account_id = req.user.accountId;

        return criteria;
    }

    byName(name) {
        return {
            name: name
        };
    }

    byEmail(email) {
        return {
            email: email
        };
    }

    byHashId(hashId) {
        return {
            hash_id: hashId
        };
    }

}

module.exports = new CriteriaFactory();


text:
<?php

namespace CrickLog\CoreBundle\Tests\Fixtures;

use Protalk\UserBundle\Entity\User;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\Persistence\ObjectManager;

class LoadUserData extends AbstractFixture
{
    public function load(ObjectManager $manager)
    {
        $userOne = new User();
        $userOne->setFirstname('Joe');
        $userOne->setLastname('Blogs');
        $userOne->setUsername('Joe Bloggs');
        $userOne->setEmail('jb@example.com');
        $userOne->setPlainPassword('123');
        $userOne->setEnabled(true);
        $userOne->setRoles(array('ROLE_USER'));

        $userTwo = new User();
        $userTwo->setFirstname('Ann');
        $userTwo->setLastname('Other');
        $userTwo->setUsername('Ann Other');
        $userTwo->setEmail('ao@example.com');
        $userTwo->setPlainPassword('123');
        $userTwo->setEnabled(true);
        $userTwo->setRoles(array('ROLE_USER'));

        $admin = new User();
        $admin->setUsername('admin');
        $admin->setEmail('admin@example.com');
        $admin->setPlainPassword('master');
        $admin->setEnabled(true);
        $admin->setRoles(array('ROLE_SUPER_ADMIN'));

        $manager->persist($userOne);
        $manager->persist($userTwo);
        $manager->persist($admin);

        $manager->flush();

        $this->addReference('userOne', $userOne);
        $this->addReference('userTwo', $userTwo);
    }
}


text:
namespace
{
	bool IsDefault(const JlsCustomParameters* pcustom)
	{
		if (pcustom->MAXVAL != 0)
			return false;

		if (pcustom->T1 != 0)
			return false;

		if (pcustom->T2 != 0)
			return false;

		if (pcustom->T3 != 0)
			return false;

		if (pcustom->RESET != 0)
			return false;

		return true;
	}
}

JpegStreamWriter::JpegStreamWriter(const JfifParameters& jfifParameters, Size size, LONG bitsPerSample, LONG ccomp) :
_bCompare(false),
_data(),
_byteOffset(0),
_lastCompenentIndex(0)
{
	if (jfifParameters.Ver)
	{
		AddSegment(JpegMarkerSegment::CreateJpegFileInterchangeFormatMarker(jfifParameters));
	}

	AddSegment(JpegMarkerSegment::CreateStartOfFrameMarker(size, bitsPerSample, ccomp));
}

JpegStreamWriter::~JpegStreamWriter()
{
	for (size_t i = 0; i < _segments.size(); ++i)
	{
		delete _segments[i];
	}
}

void JpegStreamWriter::AddColorTransform(int i)
{
	AddSegment(JpegMarkerSegment::CreateColorTransformMarker(i));
}

size_t JpegStreamWriter::Write(ByteStreamInfo info)
{
	_data = info;

	WriteByte(0xFF);
	WriteByte(JPEG_SOI);

	for (size_t i = 0; i < _segments.size(); ++i)
	{
		_segments[i]->Serialize(*this);
	}

	//_bCompare = false;

	WriteByte(0xFF);
	WriteByte(JPEG_EOI);

	return _byteOffset;
}

void JpegStreamWriter::AddScan(ByteStreamInfo info, const JlsParameters* pparams)
{
	if (!IsDefault(&pparams->custom))
	{
		AddSegment(JpegMarkerSegment::CreateJpegLSExtendedParametersMarker(pparams->custom));
	}
	else if (pparams->bitspersample > 12)
	{
		JlsCustomParameters preset = ComputeDefault((1 << pparams->bitspersample) - 1, pparams->allowedlossyerror);
		AddSegment(JpegMarkerSegment::CreateJpegLSExtendedParametersMarker(preset));
	}

	_lastCompenentIndex += 1;
	AddSegment(JpegMarkerSegment::CreateStartOfScanMarker(pparams, pparams->ilv == ILV_NONE ? _lastCompenentIndex : -1));

	int ccomp = pparams->ilv == ILV_NONE ? 1 : pparams->components;

	AddSegment(new JpegImageDataSegment(info, *pparams, ccomp));
}


text:
package model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * A list of {@link Entity}s
 */
public class EntityList extends ArrayList<Entity> implements Serializable {
    private transient List<ChangeListener> changeListenerList;

    public EntityList() {
        super();
    }

    @SuppressWarnings({"unused"})
    public EntityList(Collection<? extends Entity> c) {
        super(c);
    }

    public List<ChangeListener> getChangeListenerList() {
        if (changeListenerList == null) {
            changeListenerList = new ArrayList<>();
        }
        return changeListenerList;
    }

    @Override
    public Entity set(int index, Entity element) {
        for (ChangeListener changeListener : this.getChangeListenerList()) {
            changeListener.replaced(index, this.get(index), element);
        }
        return super.set(index, element);
    }

    @Override
    public void add(int index, Entity element) {
        for (ChangeListener changeListener : this.getChangeListenerList()) {
            changeListener.added(index, element);
        }
        super.add(index, element);
    }

    @Override
    public Entity remove(int index) {
        for (ChangeListener changeListener : this.getChangeListenerList()) {
            changeListener.removed(this.get(index));
        }
        return super.remove(index);
    }

    @Override
    public boolean remove(Object o) {
        for (ChangeListener changeListener : this.getChangeListenerList()) {
            changeListener.removed((Entity) o);
        }
        return super.remove(o);
    }

    @SuppressWarnings("unused")
    public interface ChangeListener {
        void removed(Entity item);

        void added(int index, Entity item);

        void replaced(int index, Entity oldValue, Entity newValue);
    }
}


text:
(function() {
  var BST, Node;

  Node = (function() {
    function Node(data, left, right) {
      this.data = data;
      this.left = left;
      this.right = right;
      this.show = function() {
        return this.data;
      };
    }

    return Node;

  })();

  BST = (function() {
    function BST() {
      this.root = null;
      this.insert = function(data) {
        var current, n, parent, _results;
        n = new Node(data, null, null);
        if (this.root === null) {
          return this.root = n;
        } else {
          current = this.root;
          parent = '';
          _results = [];
          while (true) {
            parent = current;
            if (data < current.data) {
              current = current.left;
              if (current === null) {
                parent.left = n;
                break;
              } else {
                _results.push(void 0);
              }
            } else {
              current = current.right;
              if (current === null) {
                parent.right = n;
                break;
              } else {
                _results.push(void 0);
              }
            }
          }
          return _results;
        }
      };
      this.getMin = function() {
        var current;
        current = this.root;
        while (current.left !== null) {
          current = current.left;
        }
        return current.data;
      };
      this.getMax = function() {
        var current;
        current = this.root;
        while (current.right !== null) {
          current = current.right;
        }
        return current.data;
      };
      this.find = function(data) {
        var current;
        current = this.root;
        while (current !== null) {
          if (current.data === data) {
            return current;
          } else if (data < current.data) {
            current = current.left;
          } else {
            current = current.right;
          }
        }
        return null;
      };
    }

    return BST;

  })();

  module.exports = BST;

}).call(this);

//# sourceMappingURL=Node.js.map


text:
0.1.0/ Unreleased
==================

### Changes

* [FEATURE] adds directory integration.


text:
window.matchMedia = window.matchMedia || function () {
	return {
		media: '',
		matches: false,
		addListener: () => undefined,
		removeListener: () => undefined
	}
}

const storageMock: Storage = {
	key: (index: number) => null,
	getItem: () => '',
	setItem: () => undefined,
	removeItem: () => undefined,
	length: 0,
	clear: () => undefined
};

(window as any).localStorage = window.localStorage || storageMock


text:
__author__ = 'tommipor'

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Text, DateTime

Base = declarative_base()
class DataClass(Base):
        __tablename__ = 'Data'
        dataID = Column(String(255), primary_key=True)
        deviceID = Column(String(255))
        allowedOrganizations = Column(Text)
        samples = Column(Text)

        def __init__(self, dataID, deviceID, allowedOrganizations, samples):
            self.dataID = dataID
            self.deviceID = deviceID
            self.allowedOrganizations = allowedOrganizations
            self.samples = samples

        def __repr__(self):
                return "<Data(%s, %s, %s, %s)>" % (self.dataID, self.deviceID, self.allowedOrganizations, self.samples)

        @property
        def columns(self):
            return [ c.name for c in self.__table__.columns ]

        @property
        def columnitems(self):
            return dict([ (c, getattr(self, c)) for c in self.columns ])

        def tojson(self):
            return self.columnitems