text:
package sorcer.core.provider.cataloger;

import com.sun.jini.start.LifeCycle;
import net.jini.core.discovery.LookupLocator;
import net.jini.core.entry.Entry;
import net.jini.core.lookup.ServiceID;
import net.jini.core.lookup.ServiceItem;
import net.jini.core.lookup.ServiceMatches;
import net.jini.core.lookup.ServiceTemplate;
import net.jini.discovery.LookupDiscoveryManager;
import net.jini.id.ReferentUuid;
import net.jini.lookup.LookupCache;
import net.jini.lookup.ServiceDiscoveryEvent;
import net.jini.lookup.ServiceDiscoveryListener;
import net.jini.lookup.ServiceDiscoveryManager;
import net.jini.lookup.entry.Name;
import net.jini.lookup.entry.UIDescriptor;
import net.jini.lookup.ui.MainUI;
import org.rioproject.admin.ServiceActivityProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import sorcer.core.exertion.NetTask;
import sorcer.core.provider.Cataloger;
import sorcer.core.provider.Provider;
import sorcer.core.provider.ServiceProvider;
import sorcer.core.provider.cataloger.ServiceCataloger.CatalogerInfo.InterfaceList;
import sorcer.core.provider.cataloger.ui.CatalogerUI;
import sorcer.core.signature.NetSignature;
import sorcer.jini.lookup.entry.SorcerServiceInfo;
import sorcer.service.Context;
import sorcer.service.Service;
import sorcer.service.Task;
import sorcer.serviceui.UIDescriptorFactory;
import sorcer.serviceui.UIFrameFactory;
import sorcer.util.GenericUtil;
import sorcer.util.SOS;
import sorcer.util.Sorcer;
import sorcer.util.SorcerUtil;

import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.rmi.server.RMIClassLoader;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * The facility for maintaining a cache of all SORCER providers {@link Service}s
 * as specified by provider.template.match=sorcer.service.Service
 * in the sorcer.env configuration file.
 *

 *

 *
It uses ServiceDiscoveryManager with lookup cache.

 *
It uses an internal map for storing services called {@link CatalogerInfo}
 *
The key of the map is an {@link InterfaceList}, the value is the list of
 * service proxies (ServiceItems)
 *
{@link InterfaceList} is a list of interfaces with equals
 * overridden such that for (interfaceList1.equals(interfaceList2)
 * returns true if all elements contained in
 * interfaceList2 are contained in interfaceList1.
 *
get and put method of {@link CatalogerInfo} are
 * overridden to do nothing.
 *

 *

 * Only access to {@link CatalogerInfo} is via a set of "service-aware" methods.
 * They include
 *

 *
addServiceItem(SeviceItem): adds an entry to this hash map
 * such that the key is the InterfaceList describing the service.
 * value is the serviceItem itself. Value is added always to the first to
 * improve load balancing heuristics (assuming that the latest served service is
 * always removed and added to the end
 *
 *
 getServiceItem(String[] interfaces), String providerName)):
 * not only returns the serviceItem with the following specs, but also removes
 * and adds the sericeItem to the end of the list to provide load-balancing
 *
 *
synchronized getServiceItem(ServiceID serviceID) returns a
 * service with a serviceID, with the same load-balancing feature mentioned
 * above
 *
 *
 getServiceMethods()) returns a hash map with the key as a
 * service interface (those interfaces package name starting with
 * sorcer.) and its value is a list of interface's method names.
 *
 *
 getMethodContext(providerName, methodName)) returns the
 * template context with which the provider is registered. This template context
 * is pulled out of the service attribute (Entry): {@link SorcerServiceInfo}.
 *

 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public class ServiceCataloger extends ServiceProvider implements Cataloger {

	/** Logger for logging information about this instance */
	private static Logger logger = LoggerFactory.getLogger(ServiceCataloger.class);

	public boolean debug = false;

	public ServiceDiscoveryManager lookupMgr;

	public LookupCache cache;

	protected final CatalogerInfo cinfo = new CatalogerInfo();

	private String[] locators = null;

	public LookupLocator[] getLL() throws RemoteException {
		LookupLocator[] specificLocators = null;
		String sls = getProperty(P_LOCATORS);

		if (sls != null)
			locators = SorcerUtil.tokenize(sls, ",");
		try {
			if (locators != null && locators.length > 0) {
				specificLocators = new LookupLocator[locators.length];
				for (int i = 0; i < specificLocators.length; i++) {
					specificLocators[i] = new LookupLocator(locators[i]);
				}
			}
			return specificLocators;
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		return null;

	}

    public UIDescriptor getMainUIDescriptor() {
        UIDescriptor uiDesc = null;
        try {
            URL uiUrl = new URL(Sorcer.getWebsterUrl() + "/sos-cataloger-"+ SOS.getSorcerVersion()+"-ui.jar");
            uiDesc = UIDescriptorFactory.getUIDescriptor(MainUI.ROLE,
                                                         new UIFrameFactory(new URL[]{uiUrl},
                                                                            CatalogerUI.class.getName(),
                                                                            "Cataloger UI",
                                                                            null));
        } catch (Exception ex) {
			logger.warn("Could not create UI descriptor", ex);
		}
        return uiDesc;
    }

	public String[] getGroups() {
		String gs = getProperty(P_GROUPS);
		String[] groups = (gs == null) ? Sorcer.getLookupGroups() : SorcerUtil
				.tokenize(gs, ",");
		return groups;
	}

	public ServiceTemplate getTemplate() throws RemoteException {
		String templateMatch = Sorcer.getProperty(P_TEMPLATE_MATCH, ""
				+ Provider.class);
		logger.info(P_TEMPLATE_MATCH + ": " + templateMatch);
		ServiceTemplate template;
		try {
			template = new ServiceTemplate(null,
					new Class[] { Class.forName(templateMatch) }, null);
			return template;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

	public ServiceCataloger() throws RemoteException {
		// do nothing
	}

	public ServiceCataloger(String[] args, LifeCycle lifeCycle)
			throws Exception {
		super(args, lifeCycle);
		init();
	}

	public void init() {
		try {
			LookupLocator[] specificLocators = null;
			String sls = getProperty(P_LOCATORS);

			if (sls != null)
				locators = SorcerUtil.tokenize(sls, " ,");
			if (locators != null && locators.length > 0) {
				specificLocators = new LookupLocator[locators.length];
				for (int i = 0; i < specificLocators.length; i++) {
					specificLocators[i] = new LookupLocator(locators[i]);
				}
			}

			String gs = getProperty(P_GROUPS);
			String[] groups = (gs == null) ? Sorcer.getLookupGroups()
					: SorcerUtil.tokenize(gs, ",");
			lookupMgr = new ServiceDiscoveryManager(new LookupDiscoveryManager(
					groups, specificLocators, null), null);

			String templateMatch = Sorcer.getProperty(P_TEMPLATE_MATCH,
					Provider.class.getName());
			ServiceTemplate template = new ServiceTemplate(null,
					new Class[] { Class.forName(templateMatch) }, null);

			cache = lookupMgr.createLookupCache(template, null,
					new CatalogerEventListener(cinfo));

			logger.info("-----------------------------");
			logger.info("Matching services that are: " + templateMatch);
			logger.info(P_GROUPS + ": " + Arrays.toString(groups));
			logger.info(P_LOCATORS + ": " + Arrays.toString(specificLocators));
			logger.info("------------------------------");
		} catch (IOException ex) {
			ex.printStackTrace();
		} catch (ClassNotFoundException cnfe) {
			cnfe.printStackTrace();
		}
	}

//	public void setLogger(Logger logger) {
//		ServiceCataloger.logger = logger;
//	}

	/**
	 * Returns a Jini ServiceItem containing SORCER service provider based on
	 * two entries provided. The first entry is a provider's service type, the
	 * second provider's name. Expected that more entries will be needed to
	 * identify a provider in the future. See also lookup for a given ServiceID.
	 *
	 * @see sorcer.core.provider.Cataloger#lookup(Class[])
	 */
	@Override
	public ServiceItem lookupItem(String providerName, Class... serviceTypes)
			throws RemoteException {
		return cinfo.getServiceItem(serviceTypes, providerName);
	}

	/**
	 * Returns a SORCER service provider identified by its primary service type.
	 *
	 * @param serviceTypes interface of a SORCER provider
	 * @return a SORCER service provider
	 * @throws RemoteException
	 */
	@Override
	public Provider lookup(Class... serviceTypes) throws RemoteException {
		return lookup(null, serviceTypes);

	}

	/**
	 * * Returns a SORCER service provider identified by its primary service
	 * type and the provider's name/
	 *
	 * @param providerName
	 *            - a provider name, a friendly provider's ID.
	 * @param serviceTypes
	 *            - interface of a SORCER provider
	 * @return a SORCER service provider
	 * @throws RemoteException
	 */
	@Override
	public Provider lookup(String providerName, Class... serviceTypes)
			throws RemoteException {
        // TODO RemoteLoggerAppender may call Cataloger to look for RemoteLogger which introduces recursion; make RLA not use Cataloger
        String mdcRemoteCall = MDC.get(MDC_SORCER_REMOTE_CALL);
        MDC.remove(MDC_SORCER_REMOTE_CALL);
        // another workaround: disable warning on ConnectionException in ProviderProxy
        //MDC.put("java.net.ConnectException.ignore", "TRUE");
        String pn = providerName;
		if (ANY.equals(providerName))
			pn = null;
		try {
			ServiceItem sItem = cinfo.getServiceItem(serviceTypes, pn);
			logger.info("lookup: sItem = " + sItem);

			if (sItem != null && (sItem.service instanceof Provider))
				return (Provider) sItem.service;
		} catch (Exception t) {
            logger.warn("Error while getting service item: " + t.getMessage());
        } finally {
            if (mdcRemoteCall != null)
                MDC.put(MDC_SORCER_REMOTE_CALL, mdcRemoteCall);
            //MDC.remove("java.net.ConnectException.ignore");
        }

		return null;
	}

	/**
	 * Returns a SORCER service provider identified by its service ID.
	 *
	 * @param sid
	 *            - provider's ID
	 * @return a SORCER service provider
	 * @throws RemoteException
	 */
	@Override
	public Provider lookup(ServiceID sid) throws RemoteException {
		if (sid == null)
			return null;
		ServiceItem sItem = cinfo.getServiceItem(sid);
		return (sItem != null && sItem.service instanceof Provider) ? (Provider) sItem.service
				: null;
	}

	@Override
	public Map<String, String> getProviderMethods() throws RemoteException {
		if (cinfo == null)
			return new HashMap();
		else
			return cinfo.getProviderMethods();
	}

	@Override
	public Map<String, URL[]>  getProviderCodebaseURLs() throws RemoteException {
		if (cinfo == null)
			return new HashMap();
		else
			return cinfo.getProviderCodebaseURLs();
	}

	/**
	 * Returns the list of available providers in this catalog.
	 *
	 * @return
	 * @throws RemoteException
	 */
	@Override
	public String[] getProviderList() throws RemoteException {
		List<ServiceItem> items = cinfo.getAllServiceItems();

		List<String> names = new ArrayList<String>();
		for (ServiceItem si : items) {
				Entry[] attributes = si.attributeSets;
				for (Entry a : attributes) {
					if (a instanceof Name) {
						names.add(((Name) a).name);
						break;
					}
				}
			}
		return names.toArray(new String[names.size()]);
	}

	@Override
	public String[] getInterfaceList(String providerName)
			throws RemoteException {
		if (cinfo == null) {
			return new String[0];
		}
		return cinfo.getInterfaceList(providerName);
	}

	@Override
	public String[] getMethodsList(String providerName, String interfaceName)
			throws RemoteException {
		if (cinfo == null) {
			return new String[0];
		}
		return cinfo.getMethodsList(providerName, interfaceName);
	}

	@Override
	public Context exertService(String providerName, Class serviceType,
			String methodName, Context theContext) throws RemoteException {
		return cinfo.exertService(providerName, serviceType, methodName,
				theContext);
	}

	@Override
	public String getServiceInfo() throws RemoteException {
		return cinfo.toString();
	}

	/**
	 * A customized "sorcer provider" aware a map of the cataloger
	 * info.
	 *

	 * The key of the cataloger info is the InterfaceList. This
	 * inner InterfaceList is an array list of interface names with
	 * overridden equals such that it follows the following
	 * semantics: arrayList1.equals(arrayList2 iff all interfaces
	 * of arrayList2 are contained in arrayList1.

	 * The key value in InterfaceList is the list of service items
	 * implementing its key interfaces. Methods get and
	 * put are overridden to do nothing.
	 *

	 * The method addServiceItem(SeviceItem) adds an entry to this
	 * map such that the key is the InterfaceList describing this
	 * service, the value is the serviceItem itself.
	 *

	 * The method
	 * getServiceItem(String[] interfaces, String providerName) not
	 * only returns the serviceItem with the following specs, but also removes
	 * and adds the sericeItem to the end of the list to provide load-balancing
	 *

	 * The method getServiceItem(ServiceID serviceID) returns a
	 * service with a given serviceID
	 *

	 * The method getProviderMethods return a map of provider's
	 * service methods
	 */
	protected static class CatalogerInfo {
		Cataloger cataloger = null;
		final ConcurrentMap<InterfaceList, List<ServiceItem>> interfaceListMap = new ConcurrentHashMap<CatalogerInfo.InterfaceList, List<ServiceItem>>();

        public ConcurrentMap<InterfaceList, List<ServiceItem>> getInterfaceListMap() {
            return interfaceListMap;
        }

		private class CatalogObservable extends Observable {
			public void tellOfAction(String action) {
				logger.info("notifiying observers!");
				logger.info("num observers" + this.countObservers());
				setChanged();
				notifyObservers(action);
			}
		}

		private String[] interfaceIgnoreList;
		private CatalogObservable observable;

		public CatalogerInfo() {
			super();
			interfaceIgnoreList = new String[8];
			interfaceIgnoreList[0] = "sorcer.core.provider.Provider";
			interfaceIgnoreList[1] = "sorcer.core.provider.AdministratableProvider";
			interfaceIgnoreList[2] = "java.rmi.Remote";
			interfaceIgnoreList[3] = "net.jini.core.constraint.RemoteMethodControl";
			interfaceIgnoreList[4] = "net.jini.security.proxytrust.TrustEquivalence";
			interfaceIgnoreList[5] = "net.jini.id.ReferentUuid";
			interfaceIgnoreList[6] = "sorcer.service.RemoteTasker";
			interfaceIgnoreList[7] = "org.rioproject.admin.ServiceActivityProvider";
			observable = new CatalogObservable();
		}

		public void setCataloger(Cataloger cataloger) {
			this.cataloger = cataloger;
		}

		public void remove(CatalogerInfo.InterfaceList key) {
			interfaceListMap.remove(key);
		}

		public void remove(ServiceItem value) {
            InterfaceList found = null;
            ServiceItem itemFound = null;
            for (Map.Entry<InterfaceList, List<ServiceItem>> entry : interfaceListMap
                    .entrySet()) {
                for (ServiceItem item : entry.getValue()) {
                    if (item.serviceID.equals(value.serviceID)) {
                        found = entry.getKey();
                        itemFound = item;
                        break;
                    }
                }
            }
        }

		public void removeServiceItem(ServiceItem sItem) {
			InterfaceList searchInterfaceList = new InterfaceList(sItem.service
					.getClass().getInterfaces());
			List<ServiceItem> value;
            logger.info("Removing ServiceItem from Cataloger: " + sItem.toString());

			for (InterfaceList key : interfaceListMap.keySet()) {
                if (key.containsAllInterfaces(searchInterfaceList)) {
					value = interfaceListMap.get(key);
                    if (value != null) {
						if (value.size() == 1)
							remove(key);
						else
							removeFrom(value, sItem);
					}
				}
			}
			observable.tellOfAction("UPDATEDPLEASE");
		}

		public void addObserver(Observer observer) {
			// lookupMgr.setGUIBrowser(model);
			observable.addObserver(observer);
		}

		public List<ServiceItem> getAll(InterfaceList interfaceList) {
			List<ServiceItem> sItems = new ArrayList<ServiceItem>();
			for (Map.Entry<InterfaceList, List<ServiceItem>> entry : interfaceListMap.entrySet()) {
                if(logger.isDebugEnabled())
				logger.debug("list = " + entry.getValue());
				if (entry.getKey().containsAllInterfaces(interfaceList)) {
					logger.info("Cataloger found matching interface list: "+ entry.getValue());
					sItems.addAll(interfaceListMap.get(entry.getKey()));
				}
			}
			return sItems;
		}

		private boolean alreadyHas(ServiceItem item, List<ServiceItem> list) {
			boolean has = false;
			for(ServiceItem si : list) {
				if(si.serviceID.equals(item.serviceID)) {
					has = true;
					break;
				}
			}
			return has;
		}

		public void addServiceItem(ServiceItem sItem) {
			InterfaceList keyList = new InterfaceList(sItem.service.getClass().getInterfaces());
			List<ServiceItem> sItems = interfaceListMap.get(keyList);
			if(sItems!=null) {
				List<ServiceItem> workingList = new ArrayList<>();
				workingList.addAll(sItems);
				boolean added = false;
				for (ServiceItem si : sItems) {
					if(!alreadyHas(si, workingList)) {
						workingList.add(0, sItem);
						added = true;
					}
				}
				interfaceListMap.put(keyList, workingList);
				if(added) {
					StringBuilder sb = new StringBuilder();
					for (ServiceItem i : workingList) {
						if (sb.length() > 0)
							sb.append("\n");
						sb.append("\t")
						  .append(getName(i.attributeSets))
						  .append(" sid: ").append(i.serviceID)
						  .append(" rid: ").append(((ReferentUuid) i.service).getReferentUuid());
					}
					logger.info("ServiceItem list for {} was {} now {}\n{}",
								getName(sItem.attributeSets),
								sItems.size(),
								workingList.size(),
								sb.toString());
				} else {
					logger.info("ServiceItem list unchanged for {}",
								getName(sItem.attributeSets));
				}
			} else {
				sItems = new ArrayList<>();
				sItems.add(0, sItem);
				interfaceListMap.put(keyList, sItems);
				logger.info("ServiceItem list created for {}",
							getName(sItem.attributeSets));
			}
			logger.debug("Added new service, calling notify");
			observable.tellOfAction("UPDATEDPLEASE");
		}

		private String getName(Entry[] entries) {
			String name = null;
			for(Entry e : entries) {
				if(e instanceof Name) {
					name = ((Name)e).name;
					break;
				}
			}
			return name;
		}

        private void removeFrom(List<ServiceItem> sis, ServiceItem si) {
			if (si.service == null)
				return;
			for (int i = 0; i < sis.size(); i++)
				if (si.service.equals(sis.get(i).service)) {
					sis.remove(i);
					return;
				}
		}

		public String toString() {
			StringBuilder sb = new StringBuilder();
			List<ServiceItem> sItems;
			for(Map.Entry<InterfaceList, List<ServiceItem>> entry : interfaceListMap.entrySet()){
				sItems = entry.getValue();
				sb.append("\n");
				if (sItems != null && sItems.size() > 0
						&& sItems.get(0) != null) {
					if (sItems.get(0).attributeSets[0] instanceof Name)
						sb.append(((Name) (sItems.get(0).attributeSets[0])).name);
					else
						sb.append(sItems.get(0).attributeSets[0]);

					for (int i = 1; i < sItems.size(); i++) {
						if (sItems.get(i).attributeSets[0] instanceof Name)
							sb.append(",").append(((Name) (sItems.get(i).attributeSets[0])).name);
						else
							sb.append(",").append(sItems.get(i).attributeSets[0]);
					}
					sb.append("==>\n");
					sb.append(entry.getKey());
				}
			}
			return sb.toString();
		}

		/**
		 * The caller of this method must follow this generic protocol
		 *

		 * first parameter = String[] of interfaces

		 * second parameter = providerName if any
		 *

		 * This method provides automatic load balancing by providing the
		 * serviceItem from the beginning and by removing it and adding to the
		 * end upon each request.
		 */
		public ServiceItem getServiceItem(Class[] interfaces,
				String providerName) {

			logger.info("providerName = " + providerName + "\ninterfaces: "
					+ GenericUtil.arrayToString(interfaces));

			List<ServiceItem> list = getAll(new InterfaceList(interfaces));
			logger.info("Cinfo getServiceItem, got: " + list);
			if (providerName != null && providerName.equals(ANY))
				providerName = null;
			if (list == null)
				return null;

			ServiceItem sItem;
			// provide load balancing and check if still alive
			if (providerName == null || providerName.length() == 0) {
				do {
					if (list.size() == 0)
						return null;
					sItem = list.remove(0);
					if (sItem != null) {
						if (isAlive(sItem)) {
							list.add(sItem);
							return sItem;
						} else {
							// not Alive anymore removing from cataloger
							removeServiceItem(sItem);
						}
					}
				} while (sItem != null);
			} else {
				net.jini.core.entry.Entry[] attrs;
				for (int i = 0; i < list.size(); i++) {
					attrs = list.get(i).attributeSets;
					for (net.jini.core.entry.Entry et : attrs) {
						if (et instanceof Name
								&& providerName.equals(((Name) et).name)) {
							sItem = list.remove(i);
                            if (sItem != null) {
                                if (isAlive(sItem)) {
                                    list.add(sItem);
                                    return sItem;
                                } else {
                                    // not Alive anymore removing from cataloger
                                    removeServiceItem(sItem);
                                }
                            }
						}
					}
				}
			}
			return null;
		}

		// there's no other better way of doing this because of the structure we
		// maintain.
		// we need to iterate through each and every one of the list and get the
		// service
		public ServiceItem getServiceItem(ServiceID serviceID) {
			Collection<List<ServiceItem>> c = interfaceListMap.values();
			if (c == null)
				return null;
			List<ServiceItem> sItems;
			ServiceItem sItem;
			for (Iterator<List<ServiceItem>> it = c.iterator(); it.hasNext();) {
				sItems = it.next();
				for (int i = 0; i < sItems.size(); i++) {
					if (serviceID.equals((sItems.get(i)).serviceID)) {
						sItem = sItems.remove(i);
						sItems.add(sItem);
						return sItem;
					}
				}
			}
			return null;
		}

		public List<ServiceItem> getAllServiceItems() {
			List<ServiceItem> items = new ArrayList<ServiceItem>();
			for (Map.Entry<InterfaceList, List<ServiceItem>> entry : interfaceListMap
					.entrySet()) {
				items.addAll(entry.getValue());
			}
			return items;
		}

		public ServiceItem[] getServiceItems(Class[] interfaces,
				String providerName, int maxItems) {
			// if maxItems is less or 0 then get all possible ServiceItems
			if (maxItems <= 0)
				maxItems = Integer.MAX_VALUE;
			if (providerName != null && providerName.equals(ANY))
				providerName = null;
			// logger.debug("Looking for interfaces: " + interfaces);
			List<ServiceItem> list = interfaceListMap.get(new InterfaceList(
					interfaces));
			// logger.debug("Got list: " + list.toString());
			if (list == null)
				return null;

			ServiceItem sItem;
			// provide load balancing
			if (providerName == null || "".equals(providerName)) {
				sItem = list.remove(0);
				list.add(sItem);
				ArrayList<ServiceItem> arItems = new ArrayList<ServiceItem>();
				Iterator<ServiceItem> it = list.iterator();
				while (it.hasNext() && arItems.size() < maxItems) {
					// Check if provider is still alive
					ServiceItem si = it.next();
					if (isAlive(si) && (!arItems.contains(si)))
						arItems.add(si);
				}
				ServiceItem[] sitems = new ServiceItem[arItems.size()];
				for (int i = 0; i < arItems.size(); i++) {
					sitems[i] = arItems.get(i);
				}
				return sitems;
			} else {
				net.jini.core.entry.Entry[] attrs;
				List<ServiceItem> slist = new ArrayList<ServiceItem>();
				Iterator<ServiceItem> it = list.iterator();
				ServiceItem si = null;
				while (it.hasNext() && slist.size() < maxItems) {
					si = it.next();
					attrs = si.attributeSets;
					if (attrs != null && attrs.length > 0
							&& (attrs[0] instanceof Name)
							&& providerName.equals(((Name) attrs[0]).name)) {
						if (isAlive(si) && (!slist.contains(si))) {
							slist.add(si);
						}
					}
				}
				ServiceItem[] sitems = new ServiceItem[slist.size()];
				for (int i = 0; i < slist.size(); i++) {
					sitems[i] = slist.get(i);
				}
				return sitems;
			}
		}

		public Map<String, String> getProviderMethods() throws RemoteException {
			logger.info("Inside GetProviderMethods");
			observable.tellOfAction("UPDATEDPLEASEPM");
			Map<String, String> map = new HashMap<String, String>();
			Collection<List<ServiceItem>> c = interfaceListMap.values();
			if (c == null) {
				return map;
			}
			Type[] clazz;
			Object service;
			String serviceName = null;
			net.jini.core.entry.Entry[] attributes;
			for (List<ServiceItem> sItems : c) {
				// get the first service proxy
				service = sItems.get(0).service;
				// get proxy interfaces
				clazz = service.getClass().getInterfaces();
				attributes = sItems.get(0).attributeSets;
				for (int i = 0; i < attributes.length; i++) {
					if (service instanceof Proxy) {
						if (attributes[i] instanceof Name) {
							serviceName = ((Name) attributes[i]).name;
							break;
						}
					} else
						serviceName = service.getClass().getName();
				}
				// list only interfaces of the Service type in package name
				if (service instanceof Service) {
					if (map.get(serviceName) == null) {
						map.put(serviceName, SorcerUtil.arrayToString(clazz)
								+ ";;" + SorcerUtil.arrayToString(attributes));
					}
				}
			}
			logger.info("getProviderMethods>>map:\n" + map);
			return map;
		}

		public Map<String, URL[]> getProviderCodebaseURLs() throws RemoteException {
			logger.info("Inside GetProviderMethods");
			observable.tellOfAction("UPDATEDPLEASEPM");
			Map<String, URL[]> map = new HashMap<String, URL[]>();
			Collection<List<ServiceItem>> c = interfaceListMap.values();
			if (c == null) {
				return map;
			}
			Type[] clazz;
			Object service;
			String serviceName = null;
			net.jini.core.entry.Entry[] attributes;
			for (List<ServiceItem> sItems : c) {
				// get the first service proxy
				service = sItems.get(0).service;
				// get proxy interfaces

				attributes = sItems.get(0).attributeSets;
				for (int i = 0; i < attributes.length; i++) {
					if (service instanceof Proxy) {
						if (attributes[i] instanceof Name) {
							serviceName = ((Name) attributes[i]).name;
							break;
						}
					} else
						serviceName = service.getClass().getName();
				}
				// list only interfaces of the Service type in package name
				if (service instanceof Service) {
					String annotation = RMIClassLoader.getClassAnnotation(service.getClass());
					if(annotation!=null && annotation.length()>0) {
						StringTokenizer tok = new StringTokenizer(annotation, " ");
						URL[] urls = new URL[tok.countTokens()];
						int i=0;
						while(tok.hasMoreTokens()) {
							String url = tok.nextToken();
							try {
								urls[i] = new URL(url);
							} catch (MalformedURLException e) {
								logger.warn(" Unable to create URL for ["+url+"]", e);
							}
							i++;
						}
						if (map.get(serviceName) == null) {
							map.put(serviceName, urls);
						}
					}
				}
			}
			logger.info("getProviderCodebaseURLs>>map:\n" + map);
			return map;
		}

		/**
		 * Returns the list of providers for a given provider name.
		 *
		 * @return
		 * @throws RemoteException
		 */
		public String[] getInterfaceList(String providerName) {
			Collection<List<ServiceItem>> c = interfaceListMap.values();
			if (c == null) {
				return new String[0];
			}
			Type[] interfaceList;
			Object service;
			String serviceName = null;
			net.jini.core.entry.Entry[] attributes;
			Set set = interfaceListMap.keySet();
			InterfaceList key;
			for (Iterator<InterfaceList> it = set.iterator(); it.hasNext();) {
				key = it.next();
				List<ServiceItem> sItems = interfaceListMap.get(key);
				for (int k = 0; k < sItems.size(); k++) {
					service = sItems.get(k).service;
					// logger.info(".........  attributes: "+ service);
					attributes = sItems.get(k).attributeSets;
					for (int i = 0; i < attributes.length; i++) {
						if (service instanceof Proxy) {
							if (attributes[i] instanceof Name) {
								serviceName = ((Name) attributes[i]).name;
								break;
							}
						} else
							serviceName = service.getClass().getName();
					}
					if (serviceName.equals(providerName)) {

						interfaceList = service.getClass().getInterfaces();

						int count = 0;
						for (int i = 0; i < interfaceList.length; i++) {
							// logger.info("interface "+interfaceList[i].toString());
							String currentInterface = interfaceList[i]
									.toString().substring(10); // remove the
							// interface
							// part!
							boolean onList = false;
							for (int j = 0; j < interfaceIgnoreList.length; j++) {
								if (currentInterface
										.equals(interfaceIgnoreList[j])) {
									onList = true;
									break;
								}
							}
							if (!onList)
								count++;

						}
						String[] toReturn = new String[count];
						count = 0;
						for (int i = 0; i < interfaceList.length; i++) {
							// logger.info("interface "+interfaceList[i].toString());
							String currentInterface = interfaceList[i]
									.toString().substring(10); // remove the
							// interface part!
							boolean onList = false;
							for (int j = 0; j < interfaceIgnoreList.length; j++) {
								if (currentInterface
										.equals(interfaceIgnoreList[j])) {
									onList = true;
									break;
								}
							}
							if (!onList) {
								toReturn[count] = currentInterface;
								count++;
							}

						}
						return toReturn;
					}
				}
			}
			return new String[0];
		}

		/**
		 * Get provider list is a method to get a hashmap with the list of
		 * providers and their service id.
		 *
		 * @return
		 * @throws RemoteException
		 */
		public String[] getMethodsList(String providerName, String interfaceName)
				throws RemoteException {
			logger.info("Inside Get Methods List");
			Collection<List<ServiceItem>> c = interfaceListMap.values();
			if (c == null) {
				return new String[0];
			}

			Class[] interfaceList;
			Object service;
			String serviceName = null;
			net.jini.core.entry.Entry[] attributes;
			logger.info("Provider Name " + providerName + " interface name "
					+ interfaceName);
			for (Map.Entry<InterfaceList, List<ServiceItem>> entry : interfaceListMap
					.entrySet()) {
				for (ServiceItem item : entry.getValue()) {
					service = item.service;
					attributes = item.attributeSets;
					for (int i = 0; i < attributes.length; i++) {
						if (service instanceof Proxy) {
							if (attributes[i] instanceof Name) {
								serviceName = ((Name) attributes[i]).name;
								break;
							}
						} else
							serviceName = service.getClass().getName();
					}
					if (serviceName.equals(providerName)) {
						interfaceList = service.getClass().getInterfaces();
						for (int i = 0; i < interfaceList.length; i++) {
							if (interfaceList[i].toString().equals(
									interfaceName)) {
								logger.info("Found interface" + interfaceName);
								Method methods[] = interfaceList[i]
										.getMethods();
								logger.info("Methods Found" + methods.length);
								String meths[] = new String[methods.length];
								for (int j = 0; j < methods.length; j++) {
									meths[j] = methods[j].getName();
								}
                                Set<String> setTemp = new HashSet(Arrays.asList(meths));
                                return setTemp.toArray(new String[setTemp.size()]);
							}

						}

					}
				}
			}
			return new String[0];
		}

		public Context exertService(String providerName, Class serviceType,
				String methodName, Context theContext)  {
			Collection<List<ServiceItem>> c = interfaceListMap.values();
			if (c == null) {
				return null;
			}
			List<ServiceItem> sItems;
			Object service;
			String serviceName = null;
			net.jini.core.entry.Entry[] attributes;
			InterfaceList key;
			for(Map.Entry<InterfaceList, List<ServiceItem>> entry : interfaceListMap.entrySet()) {
				for(ServiceItem item : entry.getValue()) {
					service = item.service;
					attributes = item.attributeSets;
					for (int i = 0; i < attributes.length; i++) {
						if (service instanceof Proxy) {
							if (attributes[i] instanceof Name) {
								serviceName = ((Name) attributes[i]).name;
								break;
							}
						} else
							serviceName = service.getClass().getName();
					}
					if (serviceName.equals(providerName)) {
						if (service instanceof sorcer.core.provider.Provider) {
							logger.info("service is a provider!");
							try {
								sorcer.core.provider.Provider temp = (sorcer.core.provider.Provider) service;
								NetSignature method = new NetSignature(
										methodName, serviceType);
								Task task = new NetTask(serviceType
										+ methodName, method);
								task.setContext(theContext);
								NetTask task2 = (NetTask) temp.exert(task,
										null);
								return task2.getContext();
							} catch (Exception e) {
								logger.info("error converting to provider"
										+ e.getMessage());
							}
						}
					}
				}
			}
			return null;
		}

		private List<String> getSelectorList(Class serviceType) {
			Method[] methods = serviceType.getMethods();
			List<String> selectors = new ArrayList<String>(methods.length);
			for (int k = 0; k < methods.length; k++)
				selectors.add(methods[k].getName());
			return selectors;
		}

		/**
		 * Returns a list of selectors of serviceType along with
		 * hash tables per each interface. The hash table key is an interface
		 * name and the value is a list of all interface selectors.
		 *
		 * @param serviceType
		 * @return list of selectors of serviceType and its superinterface hash
		 *         tables
		 */
		private List<String> getInterfaceList(Class serviceType) {
			Type type;
			Type[] clazz = serviceType.getGenericInterfaces();
			if (clazz.length == 0) {
				return getSelectorList(serviceType);
			}
			ArrayList ilist = new ArrayList();
			ilist.addAll(getSelectorList(serviceType));
			Map<String, List<String>> imap;
			for (int j = 0; j < clazz.length; j++) {
				type = clazz[j];
				imap = new HashMap();
				imap.put(((Class) type).getName(),
						getInterfaceList((Class) type));
				ilist.add(imap);
			}
			return ilist;
		}

		/**
		 * Returns a list of maps per each interface in the array clazz
		 * such that they are registered by the service provider as sorcerTypes.
		 * The hash table key is an interface name and the value is a list of
		 * all interface selectors.
		 *
		 * @param clazz
		 *            the list of all types
		 * @param sorcerTypes
		 *            the registered types by a service provider
		 * @return the list of superinterface hash tables
		 */
		private List<Map<String, List<String>>> getInterfaceList(Type[] clazz, List<String> sorcerTypes) {
			Type serviceType;
			ArrayList ilist = new ArrayList();
			Map<String, List<String>> imap;
			for (int j = 0; j < clazz.length; j++) {
				serviceType = clazz[j];
				if (sorcerTypes != null
						&& sorcerTypes
								.contains(((Class)serviceType).getName())) {
					imap = new HashMap<String, List<String>>();
					imap.put(((Class)serviceType).getName(),
							getSelectorList((Class)serviceType));
					ilist.add(imap);
				}
			}
			return ilist;
		}

		/**
		 * See above CatalogerInfo for comments.
		 */
		public static class InterfaceList extends ArrayList<Class> {
			private static final long serialVersionUID = 1L;

			public InterfaceList(Class[] clazz) {
				if (clazz != null && clazz.length > 0)
					for (int i = 0; i < clazz.length; i++)
						add(clazz[i]);
			}

			public boolean containsAllInterfaces(InterfaceList interfaceList) {
				Set<Class> all = new HashSet<Class>(this);
				for (int i = 0; i < size(); i++) {
					all.addAll(Arrays.asList(get(i).getInterfaces()));
				}
				return getServiceList(all).containsAll(
						getServiceList(interfaceList));
			}

			private List<String> getServiceList(
					Collection<Class> interfaceCollection) {
				List<String> serviceList = new ArrayList<String>();
				for (Class service : interfaceCollection) {
					serviceList.add("" + service);
				}
				return serviceList;
			}

			public boolean equals(InterfaceList otherList) {
				return this.containsAllInterfaces(otherList)
						&& otherList.containsAllInterfaces(this);
			}
		}// end of InterfaceList
	}// end of CatalogerInfo

	// As these are not remote listeners, and the CatalogerInfo is thread safe,
	// it's not important to spawn a new thread for each change in the service.
	protected static class CatalogerEventListener implements
			ServiceDiscoveryListener, Runnable {
		String msg;
		final CatalogerInfo cinfo;

		public CatalogerEventListener(CatalogerInfo cinfo) {
			this.cinfo = cinfo;
		}

		public CatalogerEventListener(CatalogerInfo cinfo, String msg) {
			this(cinfo);
			this.msg = msg;
		}

		public void serviceAdded(ServiceDiscoveryEvent ev) {
			cinfo.addServiceItem(ev.getPostEventServiceItem());
			refreshScreen("++++ SERVICE ADDED ++++");
		}

		public void serviceRemoved(ServiceDiscoveryEvent ev) {
			refreshScreen("++++ SERVICE REMOVING ++++");
			cinfo.removeServiceItem(ev.getPreEventServiceItem());
			refreshScreen("++++ SERVICE REMOVED ++++");
		}

		public void serviceChanged(ServiceDiscoveryEvent ev) {
			ServiceItem pre = ev.getPreEventServiceItem();
			ServiceItem post = ev.getPostEventServiceItem();

			// This should not happen
			if (pre == null && post == null) {
				logger.info(">>serviceChanged::Null serviceItem! ? ");
				return;
			} else if (pre.service == null && post.service != null) {
				logger.info(">>serviceChanged::The proxy's service is now not null \n");
				logger.info(">>serviceChanged::Proxy later: post.service ("
						+ post.service.getClass().getName() + ")\n");
			} else if (pre.service != null && post.service == null) {
				logger.info(">>serviceChanged::The service's proxy has become null::check codebase problem");
				logger.info(">>serviceChanged::Proxy later: pre.service ("
						+ pre.service.getClass().getName() + ")\n");
				cinfo.remove(post);
			} else {
				logger.debug("Service attribute has changed pre=" + pre
						+ " post=" + post);
				cinfo.remove(pre);
				cinfo.addServiceItem(post);
			}
			refreshScreen("++++ SERVICE CHANGED ++++");
		}

		private void refreshScreen(String msg) {
			new Thread(new CatalogerEventListener(cinfo, msg)).start();
		}

		public void run() {
            if (cinfo != null && logger.isDebugEnabled()) {
				StringBuilder buffer = new StringBuilder(msg).append("\n");
				buffer.append(cinfo).append("\n");
				logger.debug(buffer.toString());
			}
		}
	}

    /**
     * Tests if provider is still alive.
     *
     * @param si service to check
     * @return true if a provider is alive, otherwise false
     */
    private static boolean isAlive(ServiceItem si) {
        if (si == null)
            return false;
        try {
            if (si.service instanceof ServiceActivityProvider) {
                boolean result = ((ServiceActivityProvider)si.service).isActive();
            } else if (si.service instanceof Provider) {
                String name = ((Provider) si.service).getProviderName();
            }
            return true;
        } catch (Exception e) {
            logger.warn("Service ID: " + si.serviceID
					+ " is not Alive anymore");
            // throw e;
            return false;
        }
	}

	/**
	 * Returns at most maxMatches items matching the template, plus the total
	 * number of items that match the template. The return value is never null,
	 * and the returned items array is only null if maxMatches is zero. For each
	 * returned item, if the service object cannot be deserialized, the service
	 * field of the item is set to null and no exception is thrown. Similarly,
	 * if an attribute set cannot be deserialized, that element of the
	 * attributeSets array is set to null and no exception is thrown.
	 *
	 * @param tmpl
	 *            - the template to match
	 * @param maxMatches
	 * @return a ServiceMatches instance that contains at most maxMatches items
	 *         matching the template, plus the total number of items that match
	 *         the template. The return value is never null, and the returned
	 *         items array is only null if maxMatches is zero.
	 * @throws RemoteException
	 */
	public ServiceMatches lookup(ServiceTemplate tmpl, int maxMatches)
			throws RemoteException {
        List<ServiceItem> result = new LinkedList<ServiceItem>();
        if(cinfo==null){
            logger.warn("Cataloger not initialized");
        } else
        for (Map.Entry<InterfaceList, List<ServiceItem>> entry : cinfo.getInterfaceListMap().entrySet()) {
            List<ServiceItem> serviceItems;
            List<ServiceItem> down = new LinkedList<ServiceItem>();
            synchronized (entry) {
                serviceItems = new LinkedList<ServiceItem>(entry.getValue());
            }
            SRVITEM:

            for (ServiceItem serviceItem : serviceItems) {
                if (tmpl.serviceID != null && tmpl.serviceID.equals(serviceItem.serviceID)) {
                    result.add(serviceItem);
                    //serviceID is unique, stop on first matching service
                    break;
                }

                CatalogerInfo.InterfaceList interfaceList = entry.getKey();
                if (interfaceList.containsAll(Arrays.asList(tmpl.serviceTypes))) {
                    List<Entry> sItemEntryList = Arrays.asList(serviceItem.attributeSets);
                    for (Entry attr : tmpl.attributeSetTemplates) {
                        if (!sItemEntryList.contains(attr)) {
                            continue SRVITEM;
                        }
                    }
                    if (isAlive(serviceItem)) {
                        logger.info("Service " + serviceItem.serviceID + " is adding to results for: " + tmpl.toString());
                        result.add(serviceItem);
                    } else {
                        // not Alive anymore removing from cataloger
                        down.add(serviceItem);
                    }
                    if (result.size() >= maxMatches) break;
                }
            }
            synchronized (cinfo){
                for(ServiceItem serviceItem: down)
                        cinfo.removeServiceItem(serviceItem);
            }

        }
        return new ServiceMatches(result.toArray(new ServiceItem[result.size()]), result.size());
    }
	public String returnString() throws RemoteException {
		return getClass().getName() + ":" + getProviderName();
	}

}


text:
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace _02.Registration_Form_Groups {

    public partial class Registration {

        /// <summary>
        /// ErrorMessage control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::System.Web.UI.WebControls.Literal ErrorMessage;

        /// <summary>
        /// EmailTextBox control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox EmailTextBox;

        /// <summary>
        /// RegularExpressionValidatorEmail control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::System.Web.UI.WebControls.RegularExpressionValidator RegularExpressionValidatorEmail;

        /// <summary>
        /// Password control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox Password;

        /// <summary>
        /// ConfirmPassword control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox ConfirmPassword;

        /// <summary>
        /// FirstName control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox FirstName;

        /// <summary>
        /// SecondName control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox SecondName;

        /// <summary>
        /// PhoneNumber control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox PhoneNumber;

        /// <summary>
        /// PhoneNumberRegExp control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::System.Web.UI.WebControls.RegularExpressionValidator PhoneNumberRegExp;

        /// <summary>
        /// Age control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox Age;

        /// <summary>
        /// RangeValidatorAge control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::System.Web.UI.WebControls.RangeValidator RangeValidatorAge;

        /// <summary>
        /// LocalAddress control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox LocalAddress;

        /// <summary>
        /// ValidationSummaryLoginInfo control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::System.Web.UI.WebControls.ValidationSummary ValidationSummaryLoginInfo;

        /// <summary>
        /// ValidationSummaryPersonalInfo control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::System.Web.UI.WebControls.ValidationSummary ValidationSummaryPersonalInfo;

        /// <summary>
        /// ValidationSummaryContactInfo control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::System.Web.UI.WebControls.ValidationSummary ValidationSummaryContactInfo;

        /// <summary>
        /// CreateButton control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::System.Web.UI.WebControls.Button CreateButton;

        /// <summary>
        /// ResultLabel control.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::System.Web.UI.WebControls.Label ResultLabel;
    }
}

redpajama_set_name: RedPajamaGithub


text:
:mod:`c1218.connection`
=======================

.. module:: c1218.connection
   :synopsis:

Classes
-------

.. autoclass:: c1218.connection.Connection
   :members:
   :special-members: __init__
   :undoc-members:

.. autoclass:: c1218.connection.ConnectionBase
   :members:
   :special-members: __init__
   :undoc-members:


text:
var tls = require('tls');
var loginQueue = require('./lib/login-queue');
var lolPackets = require('./lib/packets');
var rtmp = require('namf/rtmpNew');
var util = require('util');
var RTMPClient = rtmp.RTMPClient;
var RTMPCommand = rtmp.RTMPCommand;
var EventEmitter = require('events').EventEmitter;
var Decoder = require('namf/amf3').Decoder;

var LolClient = function(options) {
	EventEmitter.apply(this, arguments);
	this.options = options;

	this._rtmpHosts = {
		na: 'prod.na2.lol.riotgames.com',
		euw: 'prod.eu.lol.riotgames.com',
		eune: 'prod.eun1.lol.riotgames.com',
		kr: 'prod.kr.lol.riotgames.com',
		br: 'prod.br.lol.riotgames.com',
		tr: 'prod.tr.lol.riotgames.com',
		ru: 'prod.ru.lol.riotgames.com',
		lan: 'prod.la1.lol.riotgames.com',
		las: 'prod.la2.lol.riotgames.com',
		oce: 'prod.oc1.lol.riotgames.com',
		pbe: 'prod.pbe1.lol.riotgames.com'
	};

	this._loginQueueHosts = {
		na: 'lq.na2.lol.riotgames.com',
		euw: 'lq.eu.lol.riotgames.com',
		eune: 'lq.eun1.lol.riotgames.com',
		kr: 'lq.kr.lol.riotgames.com',
		br: 'lq.br.lol.riotgames.com',
		tr: 'lq.tr.lol.riotgames.com',
		lan: 'lq.la1.lol.riotgames.com',
		las: 'lq.la2.lol.riotgames.com',
		oce: 'lq.oc1.lol.riotgames.com',
		pbe: 'lq.pbe1.lol.riotgames.com'
	};

	if (this.options.region) {
		this.options.host = this._rtmpHosts[this.options.region];
		this.options.lqHost = this._loginQueueHosts[this.options.region];
	} else {
		this.options.host = this.options.host;
		this.options.lqHost = this.options.lqHost;
	}

	this.options.port = this.options.port || 2099;
	this.options.username = this.options.username;
	this.options.password = this.options.password;

	this.options.version = this.options.version || '4.21.14_12_08_11_36';
	this.options.debug = this.options.debug || false;

	if (this.options.debug) {
		console.log(this.options);
	}
};

LolClient.prototype = EventEmitter.prototype;

LolClient.prototype.connect = function(cb) {
	var _this = this;
	this.checkLoginQueue( function(err, token) {
		if (err) {
			console.log(err);
		}
		//console.log('Setting up RTMP!');
		//_this.setupRTMP();
		_this.sslConnect( function(err, stream) {
			console.log('stream connected');
			_this.stream = stream;

			_this.setupRTMP();
		});
	});
};

LolClient.prototype.checkLoginQueue = function(cb) {
	var _this = this;
	if (this.options.debug) {
		console.log("Checking Login Queue");
	}

	loginQueue(this.options.lqHost, this.options.username, this.options.password, function(err, response) {
		if(err && _this.options.debug) {
			console.log("Login Queue Failed");
			console.log("Error: " + err);
		} else {
			if(!response.token) {
				console.log('Response object:');
				console.log(response);
				console.log('Response object token:');
				console.log(response.token);
				if (response.status === "BUSY") {
					return console.log("Server too busy right now.");
				}
				var champ = response.champ;
				var rate = response.rate;
				var delay = response.delay;
				var node = response.node;
				console.log(champ);
				console.log(rate);
				console.log(delay);
				console.log(node);
				var id = 0;
				var cur = 0;

				for (var i=0; i<response.tickers.length; i++){
					if (response.tickers[i].node == node) {
						id = response.tickers[i].id;
						cur = response.tickers[i].current;
					}
				}

				console.log("In login queue. #" + (id - cur) + " in line.");

				setTimeout( function() {
					_this.checkLoginQueue(function(err, token) {
						if (err) {
							console.log('The error is ' + err);
						}
						_this.sslConnect(function(err, stream) {
						if (err) {
							console.log('The sslConnect error is :');
							console.log(err);
						}
							console.log('stream connected');
							console.log('sslConnect stream:');
							_this.stream = stream;
							console.log(stream);
							_this.setupRTMP();
						});
					});
				}, delay);
			} else {
				if (_this.options.debug) {
					console.log("Login Queue Response: ", response);
				}
				_this.options.queueToken = response.token;
				cb(null, _this.options.queueToken);
			}
		}
	});
};

LolClient.prototype.sslConnect = function(cb) {
	if (this.options.debug) {
		console.log("Connecting to SSL");
	}

	var stream = tls.connect(/*this.options.port*/ 2099, /*this.options.host*/'prod.na2.lol.riotgames.com', {'rejectUnauthorized': true}, function() {
		console.log('tls.connect - stream');
		console.log(stream);
		stream.addListener('data', function(data){
			console.log('Listener data:');
			console.log(data);
		})
		cb(null, stream);
		console.log('Finished connecting to SSL.')
	});

	stream.on('error', function(err) {
		console.log('This is an error:' + err);
		stream.destroySoon();
	});
};

LolClient.prototype.setupRTMP = function() {
	var _this = this;

	if (this.options.debug) { console.log("Setting up RTMP Client"); }
	//console.log('setupRTMP - this.stream:');
	//console.log(this.stream);
	this.rtmp = new RTMPClient(this.stream);
	//console.log('setupRTMP - this.rtmp:');
	//console.log(this.rtmp);
	if (this.options.debug) { console.log("Handshaking RTMP"); }

	console.log(this.rtmp);
	this.rtmp.handshake(function(err) {
		if (err) {
			console.log("RTMP Handshake error");
			console.log(err);
			_this.stream.destroy();
		} else {
			console.log("performing NetConnect");
			_this.performNetConnect();
		}
	});
};

LolClient.prototype.performNetConnect = function() {
	var _this = this;

	if (this.options.debug) { console.log('Performing RTMP NetConnect'); }
	var ConnectPacket = lolPackets.ConnectPacket;
	var pkt = new ConnectPacket(this.options);
	var cmd = new RTMPCommand(0x14, 'connect', null, pkt.appObject(), [false, 'nil', '', pkt.commandObject()]);
	this.rtmp.send(cmd, function(err, result) {
		if (err) {
			if (_this.options.debug) { console.log('NetConnect failed'); }
			_this.stream.destroy();
		} else {
			if (_this.options.debug) { console.log('NetConnect success');
			console.log('performNetConnect result: ' + result); }
			_this.performLogin(result);
		}
	});
};

LolClient.prototype.performLogin = function(result) {
	var _this = this;

	if (this.options.debug) { console.log("Performing RTMP Login..."); }
	var LoginPacket = lolPackets.LoginPacket;
	this.options.dsid = result.args[0].id;

	var cmd = new RTMPCommand(0x11, null, null, null, [new LoginPacket(this.options).generate(this.options.version)]);
	this.rtmp.send(cmd, function(err, result) {
		if (err) {
			if (_this.options.debug) { console.log('RTMP Login Failed'); }
			_this.stream.destroy();
		} else {
			_this.options.clientId = result.args[0].clientId.toString('hex');

			if (_this.options.debug) { console.log('RTMP Login Success');
			console.log('performLogin result: ' + result); }
			_this.performAuthentication(result);
		}
	});
};

LolClient.prototype.performAuthentication = function(result) {
	var _this = this;
	this.options.authToken = result.args[0].body.object.token;
	if (this.options.debug) { console.log("Performing Session Authentication") }

	var AuthPacket = lolPackets.AuthPacket;
	var cmd = new RTMPCommand(0x11, null, null, null, [new AuthPacket(this.options).generate()]);

	this.rtmp.send(cmd, function(err, result) {
		if (err) {
			if (_this.options.debug) { console.log("Session Authentication Failed"); }
			_this.stream.destroy();
		} else {
			if (_this.options.debug) { console.log("Session Authentication Success");
			console.log('performAuthentication result: ' + result); }
			_this.subscribeGN(result);
		}
	});
};

LolClient.prototype.subscribeGN = function(result) {
	var _this = this;

	if (this.options.debug) { console.log("Performing GN Subscription"); }
	var GNPacket = lolPackets.GNPacket;
	var cmd = new RTMPCommand(0x11, null, null, null, [new GNPacket(this.options).generate(this.options.acctId)]);

	this.rtmp.send(cmd, function(err, result) {
		if (err) {
			if (_this.options.debug) { console.log("GN Subscription Failed"); }
			_this.stream.destroy();
		} else {
			if (_this.options.debug) { console.log("GN Subscription Success");
			console.log('GN Subscription result: ' + result); }
			_this.subscribeCN(result);
		}
	})
};

LolClient.prototype.subscribeCN = function(result) {
	var _this = this;

	if (this.options.debug) { console.log("Performing CN Subscription"); }
	var CNPacket = lolPackets.CNPacket;
	var cmd = new RTMPCommand(0x11, null, null, null, [new CNPacket(this.options).generate(this.options.acctId)]);

	this.rtmp.send(cmd, function(err, result) {
		if (err) {
			if (_this.options.debug) { console.log("CN Subscription Failed"); }
			_this.stream.destroy();
		} else {
			if (_this.options.debug) { console.log("CN Subscription Success"); }
			_this.subscribeBC(result);
		}
	})
};

LolClient.prototype.subscribeBC = function(result) {
	var _this = this;

	if (this.options.debug) { console.log("Performing BC Subscription"); }
	var BCPacket = lolPackets.GNPacket;
	var cmd = new RTMPCommand(0x11, null, null, null, [new BCPacket(this.options).generate(this.options.acctId)]);

	this.rtmp.send(cmd, function(err, result) {
		if (err) {
			if (_this.options.debug) { console.log("BC Subscription Failed"); }
			_this.stream.destroy();
		} else {
			if (_this.options.debug) { console.log("Connect Proceess Completed"); }
			_this.emit('connection');
		}
	})
};

LolClient.prototype.heartbeat = function() {
	var _this = this;

	if (this.options.debug) { console.log("Performing Heartbeat"); }

	var Heartbeat = lolPackets.HeartbeatPacket;
	var cmd = new RTMPCommand(0x11, null, null, null, [new Heartbeat(this.options).generate()]);

	this.rtmp.send(cmd, function(err, result) {
		if (err && _this.options.debug) {
			console.log("Heartbeat failed")
		} else if (_this.options.debug) {
			console.log("Heartbeat success")
		}
	});
}

LolClient.prototype.getSummonerByName = function(name, cb) {
	var _this = this;

	if ( this.options.debug) { console.log("Finding player by name: " + name); }
	var LookupPacket = lolPackets.LookupPacket;
	var cmd = new RTMPCommand(0x11, null, null, null, [new LookupPacket(this.options).generate(name)]);

	this.rtmp.send(cmd, function(err, result) {
		if (err) { return cb(err); }
		if (result != null) {
			return cb(null, result.args[0].body);
		}
	});
};

LolClient.prototype.getCurrentGameByName = function(name, cb) {
	var _this = this;

	if ( this.options.debug) { console.log("Getting current game by name: " + name); }
	var GetCurrentGamePacket = lolPackets.GetCurrentGamePacket;
	console.log("GetCurrentGamePacket: " + GetCurrentGamePacket);
	var cmd = new RTMPCommand(0x11, null, null, null, [new GetCurrentGamePacket(this.options).generate(name)]);
	console.log("cmd: " + JSON.stringify(cmd));
	this.rtmp.send(cmd, function(err, result) {
		if (err) { return cb(err); }
		if (result != null) {
			printObject(result.object);
			return cb(null, result.args[0].body);
		}
	});
};

LolClient.prototype.getSummonerStats = function(acctId, cb) {
	var _this = this;

	if ( this.options.debug) { console.log("Fetching summoner stats for account id: " + acctId); }
	var PlayerStatsPacket = lolPackets.PlayerStatsPacket;
	var cmd = new RTMPCommand(0x11, null, null, null, [new PlayerStatsPacket(this.options).generate(Number(acctId))]);

	this.rtmp.send(cmd, function(err, result) {
		if (err) { return cb(err); }
		if (result != null) {

			return cb(null, result.args[0].body);
		}
	});
};

LolClient.prototype.getMatchHistory= function(acctId, cb) {
	var _this = this;

	if ( this.options.debug) { console.log("Fetching Match History for account id: " + acctId); }
	var RecentGamesPacket = lolPackets.RecentGamesPacket;
	var cmd = new RTMPCommand(0x11, null, null, null, [new RecentGamesPacket(this.options).generate(Number(acctId))]);

	this.rtmp.send(cmd, function(err, result) {
		if (err) { return cb(err); }
		if (result != null) {
			return cb(null, result.args[0].body);
		}
	});
};

LolClient.prototype.getAggregatedStats = function(acctId, cb) {
	var _this = this;

	if ( this.options.debug) { console.log("Getting aggregated stats for account id: " + acctId); }
	var AggregatedStatsPacket = lolPackets.AggregatedStatsPacket;
	var cmd = new RTMPCommand(0x11, null, null, null, [new AggregatedStatsPacket(this.options).generate(Number(acctId))]);

	this.rtmp.send(cmd, function(err, result) {
		if (err) { return cb(err); }
		if (result != null) {
			return cb(null, result.args[0].body);
		}
	});
};

LolClient.prototype.getTeamsForSummoner = function(summonerId, cb) {
	var _this = this;

	if ( this.options.debug) { console.log("Finding teams for summoner id: " + summonerId); }
	var GetTeamsForSummonerPacket = lolPackets.GetTeamsForSummonerPacket;
	var cmd = new RTMPCommand(0x11, null, null, null, [new GetTeamsForSummonerPacket(this.options).generate(Number(summonerId))]);

	this.rtmp.send(cmd, function(err, result) {
		if (err) { return cb(err); }
		if (result != null) {
			return cb(null, result.args[0].body);
		}
	});
};

LolClient.prototype.getTeamById = function(teamId, cb) {
	var _this = this;

	if ( this.options.debug) { console.log("Finding team by team id: " + teamId); }
	var GetTeamByIdPacket = lolPackets.GetTeamByIdPacket;
	var cmd = new RTMPCommand(0x11, null, null, null, [new GetTeamByIdPacket(this.options).generate(Number(teamId))]);

	this.rtmp.send(cmd, function(err, result) {
		if (err) { return cb(err); }
		if (result != null) {
			return cb(null, result.args[0].body);
		}
	});
};

LolClient.prototype.getSummonerData = function(acctId, cb) {
	var _this = this;

	if ( this.options.debug) { console.log("Finding summoner data for account id: " + acctId); }
	var GetSummonerDataPacket = lolPackets.GetSummonerDataPacket;
	var cmd = new RTMPCommand(0x11, null, null, null, [new GetSummonerDataPacket(this.options).generate(Number(acctId))]);

	this.rtmp.send(cmd, function(err, result) {
		if (err) { return cb(err); }
		if (result != null) {
			return cb(null, result.args[0].body);
		}
	});
};

module.exports  = LolClient;

function printObject(o) {
  var out = '';
  for (var p in o) {
    out += p + ': ' + o[p] + '\n';
  }
  console.log(out);
}


text:
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var port = 8090;
var Database = require('./models/Database');

/* ------------------------ */

Database.init();

/* ------------------------ */

app.use(bodyParser.urlencoded({ extended: true }));

app.use(bodyParser.json());

app.use(function(req, res, next) {
	res.header("Access-Control-Allow-Origin", "*");
	res.header("Access-Control-Allow-Methods", ['POST', 'PUT', 'GET', 'DELETE']);
	res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
	next();
});

app.use(require('./controllers/index'));

/* ---------------------------------------------------------------------------- */

// ESTO NO ME FUNCIONA (MARIANO)
// ES MÁS, NI SIQUIERE SÉ PARA QUÉ ES.
// El back-end no tiene por qué saber nada del front-end.
// Supuestamente, estábamos haciendo un API RESTful que recibe requests de los clientes.
// Los clientes se ejecutan en máquinas personales, que nada tienen que ver con el servidor.
// El API responde con JSON, no con HTML. Es una aplicación web, no un sitio web.
// Los clientes toman la información y la muestran cómo quieran, no reciben una vista del servidor.

// Estamos teniendo un problema de diseño grave, ni siquiera sabemos lo que queremos hacer.
// Definamos algo urgente!

/*var nunjucks = require('express-nunjucks');
var path = require('path');

app.use('/public', express.static( path.join(__dirname,'../','front-end/' ) ));

app.set('view engine', 'html');

app.set('views', path.join(__dirname,'../','front-end/views') )

nunjucks.setup({
	// (default: true) controls if output with dangerous characters are escaped automatically.
	autoescape: true,
	// (default: false) throw errors when outputting a null/undefined value.
	throwOnUndefined: false,
	// (default: false) automatically remove trailing newlines from a block/tag.
	trimBlocks: false,
	// (default: false) automatically remove leading whitespace from a block/tag.
	lstripBlocks: false,
	// (default: false) if true, the system will automatically update templates when they are changed on the filesystem.
	watch: true,
	// (default: false) if true, the system will avoid using a cache and templates will be recompiled every single time.
	noCache: true,
	// (default: see nunjucks syntax) defines the syntax for nunjucks tags.
	tags: {}
}, app)*/

/* ---------------------------------------------------------------------------- */

/* ------------------------ */

app.listen(port, function () {
	console.log('Servidor iniciado. Escuchando en puerto ' + port);
});


text:
{% extends "hqwebapp/partials/download_status.html" %}
{% load i18n %}
{% block results %}

{{ on_complete_long }}

{% blocktrans with count=result.success_count %}Successfully uploaded {{ count }} mobile workers.{% endblocktrans %}

{% if result.has_errors %}

{% trans "However, we ran into problems with the following users:" %}

        {% for e in result.errors %}

{{ e }}

        {% endfor %}

{% endif %}
{% endblock results %}


text:
/**
 * @class Ext.data.JsonReader
 * @extends Ext.data.DataReader
 *
Data reader class to create an Array of {@link Ext.data.Record} objects from a JSON response
 * based on mappings in a provided {@link Ext.data.Record} constructor.

 *
Example code:

 *

var Employee = Ext.data.Record.create([
    {name: 'firstname'},                  // map the Record's "firstname" field to the row object's key of the same name
    {name: 'job', mapping: 'occupation'}  // map the Record's "job" field to the row object's "occupation" key
]);
var myReader = new Ext.data.JsonReader(
    {                             // The metadata property, with configuration options:
        totalProperty: "results", //   the property which contains the total dataset size (optional)
        root: "rows",             //   the property which contains an Array of record data objects
        idProperty: "id"          //   the property within each row object that provides an ID for the record (optional)
    },
    Employee  // {@link Ext.data.Record} constructor that provides mapping for JSON object
);

 *
This would consume a JSON data object of the form:

{
    results: 2,  // Reader's configured totalProperty
    rows: [      // Reader's configured root
        { id: 1, firstname: 'Bill', occupation: 'Gardener' },         // a row object
        { id: 2, firstname: 'Ben' , occupation: 'Horticulturalist' }  // another row object
    ]
}

 *
Automatic configuration using metaData

 *
It is possible to change a JsonReader's metadata at any time by including a <tt>metaData</tt>
 * property in the JSON data object. If the JSON data object has a <tt>metaData</tt> property, a
 * {@link Ext.data.Store Store} object using this Reader will reconfigure itself to use the newly provided
 * field definition and fire its {@link Ext.data.Store#metachange metachange} event. The metachange event
 * handler may interrogate the <tt>metaData</tt> property to perform any configuration required.
 * Note that reconfiguring a Store potentially invalidates objects which may refer to Fields or Records
 * which no longer exist.

 *
The <tt>metaData</tt> property in the JSON data object may contain:

 *

 *
any of the configuration options for this class

 *
a <tt>{@link Ext.data.Record#fields fields}</tt> property which the JsonReader will
 * use as an argument to the {@link Ext.data.Record#create data Record create method} in order to
 * configure the layout of the Records it will produce.

 *
a <tt>{@link Ext.data.Store#sortInfo sortInfo}</tt> property which the JsonReader will
 * use to set the {@link Ext.data.Store}'s {@link Ext.data.Store#sortInfo sortInfo} property

 *
any user-defined properties needed

 *

 *
To use this facility to send the same data as the example above (without having to code the creation
 * of the Record constructor), you would create the JsonReader like this:

var myReader = new Ext.data.JsonReader();

 *
The first data packet from the server would configure the reader by containing a
 * <tt>metaData</tt> property and the data. For example, the JSON data object might take
 * the form:

{
    metaData: {
        idProperty: 'id',
        root: 'rows',
        totalProperty: 'results',
        fields: [
            {name: 'name'},
            {name: 'job', mapping: 'occupation'}
        ],
        sortInfo: {field: 'name', direction:'ASC'}, // used by store to set its sortInfo
        foo: 'bar' // custom property
    },
    results: 2,
    rows: [ // an Array
        { 'id': 1, 'name': 'Bill', occupation: 'Gardener' },
        { 'id': 2, 'name': 'Ben', occupation: 'Horticulturalist' }
    ]
}

 * @cfg {String} totalProperty [total] Name of the property from which to retrieve the total number of records
 * in the dataset. This is only needed if the whole dataset is not passed in one go, but is being
 * paged from the remote server.  Defaults to <tt>total</tt>.
 * @cfg {String} successProperty [success] Name of the property from which to
 * retrieve the success attribute. Defaults to <tt>success</tt>.  See
 * {@link Ext.data.DataProxy}.{@link Ext.data.DataProxy#exception exception}
 * for additional information.
 * @cfg {String} root [undefined] Required.  The name of the property
 * which contains the Array of row objects.  Defaults to <tt>undefined</tt>.
 * An exception will be thrown if the root property is undefined. The data packet
 * value for this property should be an empty array to clear the data or show
 * no data.
 * @cfg {String} idProperty [id] Name of the property within a row object that contains a record identifier value.  Defaults to <tt>id</tt>
 * @constructor
 * Create a new JsonReader
 * @param {Object} meta Metadata configuration options.
 * @param {Array/Object} recordType
 *
Either an Array of {@link Ext.data.Field Field} definition objects (which
 * will be passed to {@link Ext.data.Record#create}, or a {@link Ext.data.Record Record}
 * constructor created from {@link Ext.data.Record#create}.

 */
Ext.data.JsonReader = function(meta, recordType){
    meta = meta || {};

    // default idProperty, successProperty & totalProperty -> "id", "success", "total"
    Ext.applyIf(meta, {
        idProperty: 'id',
        successProperty: 'success',
        totalProperty: 'total'
    });

    Ext.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);
};
Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
    /**
     * This JsonReader's metadata as passed to the constructor, or as passed in
     * the last data packet's <tt>metaData</tt> property.
     * @type Mixed
     * @property meta
     */
    /**
     * This method is only used by a DataProxy which has retrieved data from a remote server.
     * @param {Object} response The XHR object which contains the JSON data in its responseText.
     * @return {Object} data A data block which is used by an Ext.data.Store object as
     * a cache of Ext.data.Records.
     */
    read : function(response){
        var json = response.responseText;
        var o = Ext.decode(json);
        if(!o) {
            throw {message: "JsonReader.read: Json object not found"};
        }
        return this.readRecords(o);
    },

    // private function a store will implement
    onMetaChange : function(meta, recordType, o){

    },

    /**
     * @ignore
     */
    simpleAccess: function(obj, subsc) {
        return obj[subsc];
    },

    /**
     * @ignore
     */
    getJsonAccessor: function(){
        var re = /[\[\.]/;
        return function(expr) {
            try {
                return(re.test(expr)) ?
                new Function("obj", "return obj." + expr) :
                function(obj){
                    return obj[expr];
                };
            } catch(e){}
            return Ext.emptyFn;
        };
    }(),

    /**
     * Create a data block containing Ext.data.Records from a JSON object.
     * @param {Object} o An object which contains an Array of row objects in the property specified
     * in the config as 'root, and optionally a property, specified in the config as 'totalProperty'
     * which contains the total size of the dataset.
     * @return {Object} data A data block which is used by an Ext.data.Store object as
     * a cache of Ext.data.Records.
     */
    readRecords : function(o){
        /**
         * After any data loads, the raw JSON data is available for further custom processing.  If no data is
         * loaded or there is a load exception this property will be undefined.
         * @type Object
         */
        this.jsonData = o;
        if(o.metaData){
            delete this.ef;
            this.meta = o.metaData;
            this.recordType = Ext.data.Record.create(o.metaData.fields);
            this.onMetaChange(this.meta, this.recordType, o);
        }
        var s = this.meta, Record = this.recordType,
            f = Record.prototype.fields, fi = f.items, fl = f.length, v;

        // Generate extraction functions for the totalProperty, the root, the id, and for each field
        this.buildExtractors();
        var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
        if(s.totalProperty){
            v = parseInt(this.getTotal(o), 10);
            if(!isNaN(v)){
                totalRecords = v;
            }
        }
        if(s.successProperty){
            v = this.getSuccess(o);
            if(v === false || v === 'false'){
                success = false;
            }
        }

        var records = [];
        for(var i = 0; i < c; i++){
            var n = root[i];
            var record = new Record(this.extractValues(n, fi, fl), this.getId(n));
            record.json = n;
            records[i] = record;
        }
        return {
            success : success,
            records : records,
            totalRecords : totalRecords
        };
    },

    // private
    buildExtractors : function() {
        if(this.ef){
            return;
        }
        var s = this.meta, Record = this.recordType,
            f = Record.prototype.fields, fi = f.items, fl = f.length;

        if(s.totalProperty) {
            this.getTotal = this.getJsonAccessor(s.totalProperty);
        }
        if(s.successProperty) {
            this.getSuccess = this.getJsonAccessor(s.successProperty);
        }
        this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){return p;};
        if (s.id || s.idProperty) {
            var g = this.getJsonAccessor(s.id || s.idProperty);
            this.getId = function(rec) {
                var r = g(rec);
                return (r === undefined || r === "") ? null : r;
            };
        } else {
            this.getId = function(){return null;};
        }
        var ef = [];
        for(var i = 0; i < fl; i++){
            f = fi[i];
            var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
            ef.push(this.getJsonAccessor(map));
        }
        this.ef = ef;
    },

    // private extractValues
    extractValues: function(data, items, len) {
        var f, values = {};
        for(var j = 0; j < len; j++){
            f = items[j];
            var v = this.ef[j](data);
            values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
        }
        return values;
    },

    /**
     * Decode a json response from server.
     * @param {String} action [Ext.data.Api.actions.create|read|update|destroy]
     * @param {Object} response
     */
    readResponse : function(action, response) {
        var o = (response.responseText !== undefined) ? Ext.decode(response.responseText) : response;
        if(!o) {
            throw new Ext.data.JsonReader.Error('response');
        }
        if (Ext.isEmpty(o[this.meta.successProperty])) {
            throw new Ext.data.JsonReader.Error('successProperty-response', this.meta.successProperty);
        }
        // TODO, separate empty and undefined exceptions.
        if ((action === Ext.data.Api.actions.create || action === Ext.data.Api.actions.update)) {
            if (Ext.isEmpty(o[this.meta.root])) {
                throw new Ext.data.JsonReader.Error('root-emtpy', this.meta.root);
            }
            else if (o[this.meta.root] === undefined) {
                throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
            }
        }
        // make sure extraction functions are defined.
        this.ef = this.buildExtractors();
        return o;
    }
});

/**
 * @class Ext.data.JsonReader.Error
 * Error class for JsonReader
 */
Ext.data.JsonReader.Error = Ext.extend(Ext.Error, {
    constructor : function(message, arg) {
        this.arg = arg;
        Ext.Error.call(this, message);
    },
    name : 'Ext.data.JsonReader'
});
Ext.apply(Ext.data.JsonReader.Error.prototype, {
    lang: {
        'response': "An error occurred while json-decoding your server response",
        'successProperty-response': 'Could not locate your "successProperty" in your server response.  Please review your JsonReader config to ensure the config-property "successProperty" matches the property in your server-response.  See the JsonReader docs.',
        'root-undefined-response': 'Could not locate your "root" property in your server response.  Please review your JsonReader config to ensure the config-property "root" matches the property your server-response.  See the JsonReader docs.',
        'root-undefined-config': 'Your JsonReader was configured without a "root" property.  Please review your JsonReader config and make sure to define the root property.  See the JsonReader docs.',
        'idProperty-undefined' : 'Your JsonReader was configured without an "idProperty"  Please review your JsonReader configuration and ensure the "idProperty" is set (e.g.: "id").  See the JsonReader docs.',
        'root-emtpy': 'Data was expected to be returned by the server in the "root" property of the response.  Please review your JsonReader configuration to ensure the "root" property matches that returned in the server-response.  See JsonReader docs.'
    }
});


text:
/* globals console, __dirname, require */
'use strict';

var gulp = require('gulp');
var watch = require('gulp-watch');
var changed = require('gulp-changed');
var concat = require('gulp-concat');
var fs = require('fs');
var header = require('gulp-header');
var rename = require('gulp-rename');
var runSequence = require('run-sequence');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var uglify = require('gulp-uglify');
var zip = require('gulp-zip');
var karmaServer = require('karma').Server;

var CONST = {
	SRC_FOLDER: 'src',
	DIST_FOLDER: 'dist',
	DIST_FILENAME_JS: 'chordsWiki.js',
	MIN_SUFFIX: '.min.js',
	JS_SOURCE_FILES: [
		'src/js/chordsWiki.js',
		'src/js/WikiManager.js',
		'src/js/ChordsEditor.js',
		'src/js/Wiki.js',
		'src/js/chordsData.js',
		'src/js/NotesPicker.js',
		'src/js/Instrument.js',
		'src/js/Keyboard.js'
	],
	SCSS_FOLDER: 'src/sass/*.scss'
};

function concatAndMinify(src, fileName){
	return gulp.src(src)
			.pipe(sourcemaps.init())
			.pipe(concat(fileName))
			// The 'changed' task needs to know the destination directory upfront
			.pipe(changed(CONST.DIST_FOLDER))
			.pipe(gulp.dest(CONST.DIST_FOLDER))
			.pipe(rename({
				extname: CONST.MIN_SUFFIX
			}))
			.pipe(uglify({
				mangle: false
			}))
			.pipe(sourcemaps.write('.', {
				includeContent: true,
				sourceRoot: '.'
			}))
			.pipe(gulp.dest(CONST.DIST_FOLDER));
}

/* Tasks */

gulp.task('coverage', function (done) {
	// Use Karma only for the sake of producing a code coverage report
	new karmaServer({
		configFile: __dirname + '/test/karma.conf.js'
	}, done).start();
});

gulp.task('scss', function(){
	gulp.src(CONST.SCSS_FOLDER)
			.pipe(sourcemaps.init())
			.pipe(sass.sync().on('error', sass.logError))
			.pipe(sourcemaps.write('.'))
			.pipe(gulp.dest(CONST.DIST_FOLDER));
});

gulp.task('dist', function() {
	concatAndMinify(CONST.JS_SOURCE_FILES, CONST.DIST_FILENAME_JS);
});

gulp.task('default', function(callback){
	runSequence(
			'dist',
			'scss',
			function(error){
				if(error){
					console.log(error.message);
				}
				else{
					console.log('BUILD FINISHED SUCCESSFULLY');
				}
				callback(error);
			});
});

gulp.task('watch', function(){
	gulp.watch('src/sass/**/*.scss', ['scss']);
});


text:
import os
import sys
import pkg_resources

from pyramid.compat import (
    input_,
    native_,
    url_quote as compat_url_quote,
    escape,
    )

fsenc = sys.getfilesystemencoding()

class SkipTemplate(Exception):
    """
    Raised to indicate that the template should not be copied over.
    Raise this exception during the substitution of your template
    """

def copy_dir(source, dest, vars, verbosity, simulate, indent=0,
             sub_vars=True, interactive=False, overwrite=True,
             template_renderer=None, out_=sys.stdout):
    """
    Copies the ``source`` directory to the ``dest`` directory.

    ``vars``: A dictionary of variables to use in any substitutions.

    ``verbosity``: Higher numbers will show more about what is happening.

    ``simulate``: If true, then don't actually *do* anything.

    ``indent``: Indent any messages by this amount.

    ``sub_vars``: If true, variables in ``_tmpl`` files and ``+var+``
    in filenames will be substituted.

    ``overwrite``: If false, then don't every overwrite anything.

    ``interactive``: If you are overwriting a file and interactive is
    true, then ask before overwriting.

    ``template_renderer``: This is a function for rendering templates (if you
    don't want to use string.Template).  It should have the signature
    ``template_renderer(content_as_string, vars_as_dict,
    filename=filename)``.
    """
    def out(msg):
        out_.write(msg)
        out_.write('\n')
        out_.flush()
    # This allows you to use a leading +dot+ in filenames which would
    # otherwise be skipped because leading dots make the file hidden:
    vars.setdefault('dot', '.')
    vars.setdefault('plus', '+')
    use_pkg_resources = isinstance(source, tuple)
    if use_pkg_resources:
        names = sorted(pkg_resources.resource_listdir(source[0], source[1]))
    else:
        names = sorted(os.listdir(source))
    pad = ' '*(indent*2)
    if not os.path.exists(dest):
        if verbosity >= 1:
            out('%sCreating %s/' % (pad, dest))
        if not simulate:
            makedirs(dest, verbosity=verbosity, pad=pad)
    elif verbosity >= 2:
        out('%sDirectory %s exists' % (pad, dest))
    for name in names:
        if use_pkg_resources:
            full = '/'.join([source[1], name])
        else:
            full = os.path.join(source, name)
        reason = should_skip_file(name)
        if reason:
            if verbosity >= 2:
                reason = pad + reason % {'filename': full}
                out(reason)
            continue # pragma: no cover
        if sub_vars:
            dest_full = os.path.join(dest, substitute_filename(name, vars))
        sub_file = False
        if dest_full.endswith('_tmpl'):
            dest_full = dest_full[:-5]
            sub_file = sub_vars
        if use_pkg_resources and pkg_resources.resource_isdir(source[0], full):
            if verbosity:
                out('%sRecursing into %s' % (pad, os.path.basename(full)))
            copy_dir((source[0], full), dest_full, vars, verbosity, simulate,
                     indent=indent+1, sub_vars=sub_vars,
                     interactive=interactive, overwrite=overwrite,
                     template_renderer=template_renderer, out_=out_)
            continue
        elif not use_pkg_resources and os.path.isdir(full):
            if verbosity:
                out('%sRecursing into %s' % (pad, os.path.basename(full)))
            copy_dir(full, dest_full, vars, verbosity, simulate,
                     indent=indent+1, sub_vars=sub_vars,
                     interactive=interactive, overwrite=overwrite,
                     template_renderer=template_renderer, out_=out_)
            continue
        elif use_pkg_resources:
            content = pkg_resources.resource_string(source[0], full)
        else:
            f = open(full, 'rb')
            content = f.read()
            f.close()
        if sub_file:
            try:
                content = substitute_content(
                    content, vars, filename=full,
                    template_renderer=template_renderer
                    )
            except SkipTemplate:
                continue # pragma: no cover
            if content is None:
                continue  # pragma: no cover
        already_exists = os.path.exists(dest_full)
        if already_exists:
            f = open(dest_full, 'rb')
            old_content = f.read()
            f.close()
            if old_content == content:
                if verbosity:
                    out('%s%s already exists (same content)' %
                          (pad, dest_full))
                continue # pragma: no cover
            if interactive:
                if not query_interactive(
                    native_(full, fsenc), native_(dest_full, fsenc),
                    native_(content, fsenc), native_(old_content, fsenc),
                    simulate=simulate, out_=out_):
                    continue
            elif not overwrite:
                continue # pragma: no cover
        if verbosity and use_pkg_resources:
            out('%sCopying %s to %s' % (pad, full, dest_full))
        elif verbosity:
            out(
                '%sCopying %s to %s' % (pad, os.path.basename(full),
                                        dest_full))
        if not simulate:
            f = open(dest_full, 'wb')
            f.write(content)
            f.close()

def should_skip_file(name):
    """
    Checks if a file should be skipped based on its name.

    If it should be skipped, returns the reason, otherwise returns
    None.
    """
    if name.startswith('.'):
        return 'Skipping hidden file %(filename)s'
    if name.endswith(('~', '.bak')):
        return 'Skipping backup file %(filename)s'
    if name.endswith(('.pyc', '.pyo')):
        return 'Skipping %s file ' % os.path.splitext(name)[1] + '%(filename)s'
    if name.endswith('$py.class'):
        return 'Skipping $py.class file %(filename)s'
    if name in ('CVS', '_darcs'):
        return 'Skipping version control directory %(filename)s'
    return None

# Overridden on user's request:
all_answer = None

def query_interactive(src_fn, dest_fn, src_content, dest_content,
                      simulate, out_=sys.stdout):
    def out(msg):
        out_.write(msg)
        out_.write('\n')
        out_.flush()
    global all_answer
    from difflib import unified_diff, context_diff
    u_diff = list(unified_diff(
        dest_content.splitlines(),
        src_content.splitlines(),
        dest_fn, src_fn))
    c_diff = list(context_diff(
        dest_content.splitlines(),
        src_content.splitlines(),
        dest_fn, src_fn))
    added = len([l for l in u_diff if l.startswith('+')
                   and not l.startswith('+++')])
    removed = len([l for l in u_diff if l.startswith('-')
                   and not l.startswith('---')])
    if added > removed:
        msg = '; %i lines added' % (added-removed)
    elif removed > added:
        msg = '; %i lines removed' % (removed-added)
    else:
        msg = ''
    out('Replace %i bytes with %i bytes (%i/%i lines changed%s)' % (
        len(dest_content), len(src_content),
        removed, len(dest_content.splitlines()), msg))
    prompt = 'Overwrite %s [y/n/d/B/?] ' % dest_fn
    while 1:
        if all_answer is None:
            response = input_(prompt).strip().lower()
        else:
            response = all_answer
        if not response or response[0] == 'b':
            import shutil
            new_dest_fn = dest_fn + '.bak'
            n = 0
            while os.path.exists(new_dest_fn):
                n += 1
                new_dest_fn = dest_fn + '.bak' + str(n)
            out('Backing up %s to %s' % (dest_fn, new_dest_fn))
            if not simulate:
                shutil.copyfile(dest_fn, new_dest_fn)
            return True
        elif response.startswith('all '):
            rest = response[4:].strip()
            if not rest or rest[0] not in ('y', 'n', 'b'):
                out(query_usage)
                continue
            response = all_answer = rest[0]
        if response[0] == 'y':
            return True
        elif response[0] == 'n':
            return False
        elif response == 'dc':
            out('\n'.join(c_diff))
        elif response[0] == 'd':
            out('\n'.join(u_diff))
        else:
            out(query_usage)

query_usage = """\
Responses:
  Y(es):    Overwrite the file with the new content.
  N(o):     Do not overwrite the file.
  D(iff):   Show a unified diff of the proposed changes (dc=context diff)
  B(ackup): Save the current file contents to a .bak file
            (and overwrite)
  Type "all Y/N/B" to use Y/N/B for answer to all future questions
"""

def makedirs(dir, verbosity, pad):
    parent = os.path.dirname(os.path.abspath(dir))
    if not os.path.exists(parent):
        makedirs(parent, verbosity, pad)  # pragma: no cover
    os.mkdir(dir)

def substitute_filename(fn, vars):
    for var, value in vars.items():
        fn = fn.replace('+%s+' % var, str(value))
    return fn

def substitute_content(content, vars, filename='<string>',
                       template_renderer=None):
    v = standard_vars.copy()
    v.update(vars)
    return template_renderer(content, v, filename=filename)

def html_quote(s):
    if s is None:
        return ''
    return escape(str(s), 1)

def url_quote(s):
    if s is None:
        return ''
    return compat_url_quote(str(s))

def test(conf, true_cond, false_cond=None):
    if conf:
        return true_cond
    else:
        return false_cond

def skip_template(condition=True, *args):
    """
    Raise SkipTemplate, which causes copydir to skip the template
    being processed.  If you pass in a condition, only raise if that
    condition is true (allows you to use this with string.Template)

    If you pass any additional arguments, they will be used to
    instantiate SkipTemplate (generally use like
    ``skip_template(license=='GPL', 'Skipping file; not using GPL')``)
    """
    if condition:
        raise SkipTemplate(*args)

standard_vars = {
    'nothing': None,
    'html_quote': html_quote,
    'url_quote': url_quote,
    'empty': '""',
    'test': test,
    'repr': repr,
    'str': str,
    'bool': bool,
    'SkipTemplate': SkipTemplate,
    'skip_template': skip_template,
    }


text:
<?php
declare(strict_types=1);

namespace Cake\Collection\Iterator;

use Cake\Collection\Collection;
use Cake\Collection\CollectionInterface;
use Cake\Collection\CollectionTrait;
use MultipleIterator;
use Serializable;

/**
 * Creates an iterator that returns elements grouped in pairs
 *
 * ### Example
 *
 * ```
 *  $iterator = new ZipIterator([[1, 2], [3, 4]]);
 *  $iterator->toList(); // Returns [[1, 3], [2, 4]]
 * ```
 *
 * You can also chose a custom function to zip the elements together, such
 * as doing a sum by index:
 *
 * ### Example
 *
 * ```
 *  $iterator = new ZipIterator([[1, 2], [3, 4]], function ($a, $b) {
 *    return $a + $b;
 *  });
 *  $iterator->toList(); // Returns [4, 6]
 * ```
 */
class ZipIterator extends MultipleIterator implements CollectionInterface, Serializable
{
    use CollectionTrait;

    /**
     * The function to use for zipping items together
     *
     * @var callable|null
     */
    protected $_callback;

    /**
     * Contains the original iterator objects that were attached
     *
     * @var array
     */
    protected $_iterators = [];

    /**
     * Creates the iterator to merge together the values by for all the passed
     * iterators by their corresponding index.
     *
     * @param array $sets The list of array or iterators to be zipped.
     * @param callable|null $callable The function to use for zipping the elements of each iterator.
     */
    public function __construct(array $sets, ?callable $callable = null)
    {
        $sets = array_map(function ($items) {
            return (new Collection($items))->unwrap();
        }, $sets);

        $this->_callback = $callable;
        parent::__construct(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_NUMERIC);

        foreach ($sets as $set) {
            $this->_iterators[] = $set;
            $this->attachIterator($set);
        }
    }

    /**
     * Returns the value resulting out of zipping all the elements for all the
     * iterators with the same positional index.
     *
     * @return array
     */
    #[\ReturnTypeWillChange]
    public function current()
    {
        if ($this->_callback === null) {
            return parent::current();
        }

        return call_user_func_array($this->_callback, parent::current());
    }

    /**
     * Returns a string representation of this object that can be used
     * to reconstruct it
     *
     * @return string
     */
    public function serialize(): string
    {
        return serialize($this->_iterators);
    }

    /**
     * Magic method used for serializing the iterator instance.
     *
     * @return array
     */
    public function __serialize(): array
    {
        return $this->_iterators;
    }

    /**
     * Unserializes the passed string and rebuilds the ZipIterator instance
     *
     * @param string $iterators The serialized iterators
     * @return void
     */
    public function unserialize($iterators): void
    {
        parent::__construct(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_NUMERIC);
        $this->_iterators = unserialize($iterators);
        foreach ($this->_iterators as $it) {
            $this->attachIterator($it);
        }
    }

    /**
     * Magic method used to rebuild the iterator instance.
     *
     * @param array $data Data array.
     * @return void
     */
    public function __unserialize(array $data): void
    {
        parent::__construct(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_NUMERIC);

        $this->_iterators = $data;
        foreach ($this->_iterators as $it) {
            $this->attachIterator($it);
        }
    }
}


text:
//------------------------------------------------------------------------------
// <copyright file="CalibrationDeviceType.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// </copyright>
//------------------------------------------------------------------------------

namespace Microsoft.Azure.Kinect.Sensor
{
    /// <summary>
    /// Specifies a type of calibration.
    /// </summary>
    [Native.NativeReference("k4a_calibration_type_t")]
    public enum CalibrationDeviceType
    {
        /// <summary>
        /// Calibration type is unknown.
        /// </summary>
        [Native.NativeReference("K4A_CALIBRATION_TYPE_UNKNOWN")]
        Unknown = -1,

        /// <summary>
        /// Depth sensor.
        /// </summary>
        [Native.NativeReference("K4A_CALIBRATION_TYPE_DEPTH")]
        Depth,

        /// <summary>
        /// Color sensor.
        /// </summary>
        [Native.NativeReference("K4A_CALIBRATION_TYPE_COLOR")]
        Color,

        /// <summary>
        /// Gyroscope sensor.
        /// </summary>
        [Native.NativeReference("K4A_CALIBRATION_TYPE_GYRO")]
        Gyro,

        /// <summary>
        /// Accelerometer sensor.
        /// </summary>
        [Native.NativeReference("K4A_CALIBRATION_TYPE_ACCEL")]
        Accel,

        /// <summary>
        /// Number of types excluding unknown type.
        /// </summary>
        [Native.NativeReference("K4A_CALIBRATION_TYPE_NUM")]
        Num,
    }
}


text:
/**
 * @author sunag / http://www.sunag.com.br/
 */

THREE.FloatNode = function( value ) {

	THREE.InputNode.call( this, 'fv1', { share: false } );

	this.value = [ value || 0 ];

};

THREE.FloatNode.prototype = Object.create( THREE.InputNode.prototype );
THREE.FloatNode.prototype.constructor = THREE.FloatNode;

Object.defineProperties( THREE.FloatNode.prototype, {
	number: {
		get: function() {

			return this.value[ 0 ];

		},
		set: function( val ) {

			this.value[ 0 ] = val;

		}
	}
} );