text:
/**
 */
package iso20022;

import java.lang.String;

import org.eclipse.emf.common.util.EList;

/**
 *
 * A representation of the model object 'Code Set'.
 *
 *
 *
 * Set of Codes grouped together to characterize all the values of an attribute.
 *
 *
 *

 * The following features are supported:
 *

 *

 *
{@link iso20022.CodeSet#getTrace Trace}

 *
{@link iso20022.CodeSet#getDerivation Derivation}

 *
{@link iso20022.CodeSet#getIdentificationScheme Identification Scheme}

 *
{@link iso20022.CodeSet#getCode Code}

 *

 *
 * @see iso20022.Iso20022Package#getCodeSet()
 * @model
 * @generated
 */
public interface CodeSet extends iso20022.String {
	/**
	 * Returns the value of the 'Trace' reference.
	 * It is bidirectional and its opposite is '{@link iso20022.CodeSet#getDerivation Derivation}'.
	 *
	 *
	 *
	 * The CodeSet that this CodesSet is derived from.
	 *
	 * @return the value of the 'Trace' reference.
	 * @see #setTrace(CodeSet)
	 * @see iso20022.Iso20022Package#getCodeSet_Trace()
	 * @see iso20022.CodeSet#getDerivation
	 * @model opposite="derivation" ordered="false"
	 *        annotation="urn:iso:std:iso:20022:2013:ecore:extension basis='IMPLEMENTATION_ENHANCEMENT' description='Traces are represented as a direct reference to the traced-to repository concept instead of using an intermediate Trace meta class'"
	 * @generated
	 */
	CodeSet getTrace();

	/**
	 * Sets the value of the '{@link iso20022.CodeSet#getTrace Trace}' reference.
	 *
	 *
	 * @param value the new value of the 'Trace' reference.
	 * @see #getTrace()
	 * @generated
	 */
	void setTrace(CodeSet value);

	/**
	 * Returns the value of the 'Derivation' reference list.
	 * The list contents are of type {@link iso20022.CodeSet}.
	 * It is bidirectional and its opposite is '{@link iso20022.CodeSet#getTrace Trace}'.
	 *
	 *
	 *
	 * The CodeSets which are derived from this CodeSet.
	 *
	 * @return the value of the 'Derivation' reference list.
	 * @see iso20022.Iso20022Package#getCodeSet_Derivation()
	 * @see iso20022.CodeSet#getTrace
	 * @model opposite="trace" ordered="false"
	 *        annotation="urn:iso:std:iso:20022:2013:ecore:extension basis='IMPLEMENTATION_ENHANCEMENT' description='Traces are represented as a direct reference to the traced-to repository concept instead of using an intermediate Trace meta class'"
	 * @generated
	 */
	EList<CodeSet> getDerivation();

	/**
	 * Returns the value of the 'Identification Scheme' attribute.
	 *
	 *
	 *
	 * Uniquely identifies a set of Codes through a Uniform Resource Identifier (URI).
	 *
	 * @return the value of the 'Identification Scheme' attribute.
	 * @see #setIdentificationScheme(String)
	 * @see iso20022.Iso20022Package#getCodeSet_IdentificationScheme()
	 * @model ordered="false"
	 * @generated
	 */
	String getIdentificationScheme();

	/**
	 * Sets the value of the '{@link iso20022.CodeSet#getIdentificationScheme Identification Scheme}' attribute.
	 *
	 *
	 * @param value the new value of the 'Identification Scheme' attribute.
	 * @see #getIdentificationScheme()
	 * @generated
	 */
	void setIdentificationScheme(String value);

	/**
	 * Returns the value of the 'Code' containment reference list.
	 * The list contents are of type {@link iso20022.Code}.
	 * It is bidirectional and its opposite is '{@link iso20022.Code#getOwner Owner}'.
	 *
	 *
	 *
	 * A set of Codes belonging to the same CodeSet
	 *
	 * @return the value of the 'Code' containment reference list.
	 * @see iso20022.Iso20022Package#getCodeSet_Code()
	 * @see iso20022.Code#getOwner
	 * @model opposite="owner" containment="true"
	 * @generated
	 */
	EList getCode();

} // CodeSet


text:
package org.wso2.carbon.registry.core;

import org.wso2.carbon.registry.core.config.RegistryContext;
import org.wso2.carbon.registry.core.dao.ResourceDAO;
import org.wso2.carbon.registry.core.dataaccess.DataAccessManager;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.jdbc.dataobjects.ResourceDO;
import org.wso2.carbon.registry.core.session.CurrentSession;
import org.wso2.carbon.registry.core.utils.RegistryUtils;
import org.wso2.carbon.user.core.UserRealm;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

/**
 * Represents any file or collection stored in the registry. It encapsulates both the content of the
 * entity and its meta data. In addition to files and collections, instances of Resource are used to
 * represent results of runtime queries. In such scenarios, comments, tags, ratings as well as
 * collections of comments, etc. are also represented by Resource objects.
 *

 * Each resource instance contains a unique path within a Registry instance. {@link
 * Registry#get(String)} method invocation using this path gives an instance of that resource. This
 * path can be combined with the base URL of the registry server to generate a URI for the
 * resource.
 *

 * Handling content
 *

 * Contents of resource can be set either as an input stream or an object. If an input stream is
 * set, an unique file based content will be created for the given input stream. If an object of
 * type byte[] or String is set, an in-memory input stream will be created from it and then a
 * unique file based input stream is created. If an object of any other type is set, there should be
 * a handler to convert it to an input stream before reaching the repository.
 *

 * When a resource is retrieved from the database layer, its content is not retrieved from the
 * database. Instead, UUID referring to the database content is stored in dbBasedContentID. When the
 * content is first accessed, a file based input stream is created from the database content and
 * fileBasedContentID is set (fileBasedContentID = dbBasedContentID).
 */
public class ResourceImpl implements Resource {

    /**
     * UUID to identify the resource. currently this is same as the path
     */
    protected String id;

    /**
     * Snapshot for which this resource instance is created. Any resource and all its version-ed
     * data can be accessed only using the resource ID and the version number. But snapshot ID is
     * required to track currently accessing snapshot. Note that it is not possible to derive
     * snapshot ID from the resource ID and the version number, as there can be multiple snapshots
     * using the same version.
     */
    protected long snapshotID;

    /**
     * Version of this instance of the resource. Version-ed attributes (e.g. content, last modified
     * date) can be accessed by using the combination of id and versionNumber.
     */
    protected long versionNumber;

    /**
     * User name of the user who added the resource to the registry.
     */
    protected String authorUserName;

    /**
     * Time at which the resource is first added to the registry.
     */
    protected long createdTime;

    /**
     * User name of the user who modified the resource most recently.
     */
    protected String lastUpdaterUserName;

    /**
     * Time at which the resource modified most recently.
     */
    protected long lastModified;

    /**
     * Description about the resource. This may contain any text including HTML fragments.
     */
    protected String description;

    /**
     * Unique path of the resource within the registry. This is generated by appending all ascendant
     * paths to the resource name separated by "/". For example assume that the resource name is
     * "users.xml". config.xml if inside the collection named "config". config collection is inside
     * the root level collection named "servers". Then the path of the resource is
     * /servers/config/users.xml.
     */
    protected String path;

    /**
     * The matching snapshot identifier.
     */
    protected long matchingSnapshotID;

    /**
     * The permanent path of the resource. This is a path that will not change for the given
     * resource's lifetime.
     */
    protected String permanentPath;

    /**
     * Media type of the resource. Each resource can have a media type associated with it. This can
     * be either a standard MIME media type or a custom media type defined by the users of the
     * registry. Media type is used to activate media type handlers defined in the registry. Thus,
     * by defining a media type for a resource and by registering a media type handler to handle
     * that media type, it is possible to apply special processing for resources.
     */
    protected String mediaType;

    /**
     * Path of the parent collection of the resource. If the resource path is
     * /servers/config/users.xml, parent path is /servers/config.
     */
    protected String parentPath;

    /**
     * Used to detect whether the resource content is modified after it is retrieved from the
     * Registry. If this is set to true at the time of adding the resource back to the Registry, new
     * version will be created.
     */
    protected boolean contentModified;

    /**
     * Used to detect whether properties of this resource is modified since retrieval from the
     * repository. If true, properties will be updated and new version will be created upon putting
     * this resource to the repository.
     */
    protected boolean propertiesModified;

    /**
     * Determines whether the resource is subjected to changes, which causes it to create a new
     * version. If true, a new version will be created upon adding the resource to the repository.
     */
    protected boolean versionableChange;

    /**
     * Normal resources have the state RegistryConstants.ACTIVE_STATE (100) Deleted resources have
     * the state RegistryConstants.DELETED_STATE (101)
     */
    protected int state;

    /**
     * Properties associated with the resource. A resource can contain zero or more properties,
     * where each property is a name->value pair. Both name and the value should be strings.
     */
    protected Properties properties = new Properties();

    /**
     * UUID of the content stored in the database. This ID is set when a resource is retrieved from
     * the database. Upon the first getContentStream() call, a file based content will be created
     * from this database based content and file based content ID will be set.
     */
    protected int dbBasedContentID = -1;

    /**
     * Content of the resource. Object and the type stored in this field depends on the resource
     * type. If the resource is a file with no special media type handling, this contains an array
     * of bytes (byte[]) containing the raw bytes of the file. If the resource is a collection, this
     * contains a String[] containing the paths of child resources. If the resource is processed by
     * a media type handler, it is up to the media type handler to set a content. In that case
     * content can be anything ranging from String to custom type. Therefore, clients of the API
     * should be aware of the media type and the content for that media type.
     */
    protected Object content;

    /**
     * Specified whether the resource is a collection (directory) or a file. By default all
     * resources are considered as files. If you want to make a collection, you have to explicitly
     * set the directory field to true.
     */
    protected boolean directory = false;

    /**
     * Content of the resource, represented as a input stream.
     */
    //protected InputStream contentStream;

    /**
     * The data access manager is to be used only by the resource implementation and users of the
     * resource are not needed to use this. Some attributes of the resource (e.g. content) is
     * fetched upon the first request to optimize the response time. Getters of such attributes use
     * this data access manager to fetch the values from the database.
     */
    protected DataAccessManager dataAccessManager;

    /**
     * Resources and collections can be accessed outside the user registry. There are some
     * operations in these entities that require fetching fresh data, that are not authorized
     * previously. For authorizing those data, it is necessary to store the user name and the realm
     * of the user who retrieved the resource/collection instance.
     */
    protected String userName;

    /**
     * Resources and collections can be accessed outside the user registry. There are some
     * operations in these entities that require fetching fresh data, that are not authorized
     * previously. For authorizing those data, it is necessary to store the user name and the realm
     * of the user who retrieved the resource/collection instance.
     */
    protected UserRealm userRealm;

    /**
     * tenant id resource belongs to
     */
    protected int tenantId;

    /**
     * Resource DAO instance to access the database directly. Note that the Version-ed ResourceDAO
     * is thread safe, so it is possible to keep a single instance for the resource.
     */
    protected ResourceDAO resourceDAO;

    /**
     * path id, if collection - id of the path of the collection if non-collection - id of the path
     * of the non-collection
     */
    protected int pathID;

    /**
     * the name of the resource if collection - NULL non-collection - the name of the resource..
     */
    protected String name;

    /**
     * When a clone of an existing resource is created, a reference is maintained to the original
     * resource so that the content etc can be obtained on-demand.
     */
    private ResourceImpl original;

    /*
     * Defines the UUID of the resource
     */
    protected String uuid;

    /**
     * Default constructor for the resource. Creates an empty resource.
     */

    public ResourceImpl() {
        if (RegistryContext.getBaseInstance() != null) {
            this.dataAccessManager = RegistryContext.getBaseInstance().getDataAccessManager();
        } else {
            this.dataAccessManager = null;
        }
        if (dataAccessManager != null) {
            this.resourceDAO = dataAccessManager.getDAOManager().getResourceDAO();
        }
        this.id = null;
        this.snapshotID = -1;
        this.matchingSnapshotID = -1;
    }

    /**
     * Construct a resource with given path and resource data object.
     *
     * @param path       the path of the resource.
     * @param resourceDO the resource data object.
     */
    public ResourceImpl(String path, ResourceDO resourceDO) {
        this.id = path;
        this.snapshotID = -1;
        this.versionNumber = resourceDO.getVersion();
        this.authorUserName = resourceDO.getAuthor();
        this.createdTime = resourceDO.getCreatedOn();
        this.lastUpdaterUserName = resourceDO.getLastUpdater();
        this.lastModified = resourceDO.getLastUpdatedOn();
        this.description = resourceDO.getDescription();
        this.path = path;
        this.matchingSnapshotID = -1;
        this.mediaType = resourceDO.getMediaType();
        this.parentPath = RegistryUtils.getParentPath(path);
        this.contentModified = true;
        this.propertiesModified = true;
        this.versionableChange = true;
        this.state = -1;
        this.dbBasedContentID = resourceDO.getContentID();
        this.content = null;
        if (RegistryContext.getBaseInstance() != null) {
            this.dataAccessManager = RegistryContext.getBaseInstance().getDataAccessManager();
        } else {
            this.dataAccessManager = null;
        }
        if (dataAccessManager != null) {
            this.resourceDAO = dataAccessManager.getDAOManager().getResourceDAO();
        }
        this.userName = null;
        this.userRealm = null;
        this.pathID = resourceDO.getPathID();
        this.name = resourceDO.getName();
        this.uuid = resourceDO.getUUID();
    }

    /**
     * A copy constructor used to create a shallow-copy of this resource.
     *
     * @param resource the resource of which the copy is created.
     */
    public ResourceImpl(ResourceImpl resource) {
        this.id = resource.id;
        this.snapshotID = resource.snapshotID;
        this.versionNumber = resource.versionNumber;
        this.authorUserName = resource.authorUserName;
        this.createdTime = resource.createdTime;
        this.lastUpdaterUserName = resource.lastUpdaterUserName;
        this.lastModified = resource.lastModified;
        this.description = resource.description;
        this.path = resource.path;
        this.matchingSnapshotID = resource.matchingSnapshotID;
        this.permanentPath = resource.permanentPath;
        this.mediaType = resource.mediaType;
        this.parentPath = resource.parentPath;
        this.contentModified = resource.contentModified;
        this.propertiesModified = resource.propertiesModified;
        this.versionableChange = resource.versionableChange;
        this.state = resource.state;
        this.directory = resource.directory;
        this.userName = resource.userName;
        this.tenantId = resource.tenantId;
        this.pathID = resource.pathID;
        this.name = resource.name;
        this.dbBasedContentID = resource.dbBasedContentID;
        this.properties.putAll(resource.properties);

        this.content = resource.content;
        if (resource.content == null) {
            this.original = resource;
        }
        this.dataAccessManager = resource.dataAccessManager;
        this.userRealm = resource.userRealm;
        this.resourceDAO = resource.resourceDAO;
        this.uuid = resource.getUUID();
    }

    /**
     * Method to get the UUID
     *
     * @return the UUID of the resource
     */
    public String getUUID() {
        return uuid;
    }

    /**
     * Method to set the UUID of the resource
     *
     * @param uuid the UUID of the resource
     */
    public void setUUID(String uuid) {
        this.uuid = uuid;
    }

    /**
     * Method to set the data access manager.
     *
     * @param dataAccessManager the data access manager.
     */
    public void setDataAccessManager(DataAccessManager dataAccessManager) {
        this.dataAccessManager = dataAccessManager;
        if (dataAccessManager != null) {
            this.resourceDAO = dataAccessManager.getDAOManager().getResourceDAO();
        }
    }

    /**
     * Method to set the user name.
     *
     * @param userName the user name.
     */
    public void setUserName(String userName) {
        this.userName = userName;
    }

    /**
     * Method to set the user realm.
     *
     * @param userRealm the user realm.
     */
    public void setUserRealm(UserRealm userRealm) {
        this.userRealm = userRealm;
    }

    /**
     * Method to set the tenant id associated with the resource.
     *
     * @param tenantId the tenant id.
     */
    public void setTenantId(int tenantId) {
        this.tenantId = tenantId;
    }

    /**
     * The Resource ID, In the default implementation this returns the path.
     *
     * @return the resource id
     */
    public String getId() {
        return path;
    }

    /**
     * Method to set the resource id, currently it will just set the path.
     *
     * @param id the path
     */
    public void setId(String id) {
        this.path = id;
    }

    /**
     * Method to get the snapshot id.
     *
     * @return the snapshot id.
     */
    @SuppressWarnings("unused")
    public long getSnapshotID() {
        return snapshotID;
    }

    /**
     * Method to set the snapshot id.
     *
     * @param snapshotID the snapshot id.
     */
    public void setSnapshotID(long snapshotID) {
        this.snapshotID = snapshotID;
    }

    /**
     * Method to get the version number.
     *
     * @return the version number.
     */
    public long getVersionNumber() {
        return versionNumber;
    }

    /**
     * Method to set the version number.
     *
     * @param versionNumber the version number.
     */
    public void setVersionNumber(long versionNumber) {
        this.versionNumber = versionNumber;
    }

    /**
     * Method to get the author user name.
     *
     * @return the author user name.
     */
    public String getAuthorUserName() {
        return authorUserName;
    }

    /**
     * Method to set the author user name.
     *
     * @param authorUserName the author user name.
     */
    public void setAuthorUserName(String authorUserName) {
        this.authorUserName = authorUserName;
    }

    /**
     * Method to get the created time.
     *
     * @return the created time.
     */
    public Date getCreatedTime() {
        return new Date(createdTime);
    }

    /**
     * Method to set the created time.
     *
     * @param createdTime the created time.
     */
    public void setCreatedTime(Date createdTime) {
        this.createdTime = createdTime.getTime();
    }

    /**
     * Method to get the created time.
     *
     * @return the created time
     */
    public Date getLastModified() {
        return new Date(lastModified);
    }

    /**
     * Method to set the last modified date.
     *
     * @param lastModified the last modified date.
     */
    public void setLastModified(Date lastModified) {
        this.lastModified = lastModified.getTime();
    }

    /**
     * Method to get the description.
     *
     * @return the description.
     */
    public String getDescription() {
        return description;
    }

    /**
     * Method to set the description.
     *
     * @param description the description.
     */
    public void setDescription(String description) {
        this.description = description;
        versionableChange = true;
    }

    /**
     * Method to get the path. the unique identifier of the resources in the present state.
     *
     * @return the path.
     */
    public String getPath() {
        return path;
    }

    /**
     * Method to get the path. the unique identifier of the resources in the present state.
     *
     * @param path the path.
     */
    public void setPath(String path) {
        this.path = path == null ? null : preparePath(path);
    }

    /**
     * Method to get the matching snapshot id.
     *
     * @return the snapshot id.
     */
    public long getMatchingSnapshotID() {
        return matchingSnapshotID;
    }

    /**
     * Method to set the matching snapshot id.
     *
     * @param matchingSnapshotID the snapshot id.
     */
    public void setMatchingSnapshotID(long matchingSnapshotID) {
        this.matchingSnapshotID = matchingSnapshotID;

        if (matchingSnapshotID == -1) {
            permanentPath = null;
        } else {
            permanentPath =
                    path + RegistryConstants.URL_SEPARATOR + "version:" + matchingSnapshotID;
        }
    }

    /**
     * Method to get the permanent path.
     *
     * @return the permanent path.
     */
    public String getPermanentPath() {
        return permanentPath;
    }

    /**
     * Method to get the media type.
     *
     * @return the media type.
     */
    public String getMediaType() {
        return mediaType;
    }

    /**
     * Method to set the media type.
     *
     * @param mediaType the media type.
     */
    public void setMediaType(String mediaType) {
        if (mediaType != null) {
            mediaType = (mediaType.trim().equals("")) ? null : mediaType;
        }
        this.mediaType = mediaType;
        versionableChange = true;
    }

    /**
     * Method to get the parent path.
     *
     * @return the parent path.
     */
    public String getParentPath() {
        if (parentPath != null) {
            return parentPath;
        }
        if ((path == null) || path.length() == 1) {
            return null;
        }
        int i = path.lastIndexOf('/');
        return path.substring(0, i);
    }

    /**
     * Method to set the parent path.
     *
     * @param parentPath the parent path.
     */
    public void setParentPath(String parentPath) {
        this.parentPath = parentPath;
    }

    /**
     * Method to get the state.
     *
     * @return the state.
     */
    public int getState() {
        return state;
    }

    /**
     * Method to set the state.
     *
     * @param state the state.
     */
    public void setState(int state) {
        this.state = state;
    }

    /**
     * Get the property value for the given key, if there are multiple value for that key, it will
     * return the first value.
     *
     * @param key the property key.
     *
     * @return the property value.
     */
    public String getProperty(String key) {

        List<String> propValues = getPropertyValues(key);
        if (propValues == null) {
            return null;
        } else {
            return propValues.get(0);
        }
    }

    /**
     * Returns the list of values for the given property name. Note that these values are read-only.
     * Changes made to these values will not be persisted on putting the resource.
     *
     * @param key Key of the property.
     *
     * @return List of values of the given property key.
     */
    @SuppressWarnings("unchecked")
    // We are certain that we have a list of strings in this case.
    public List<String> getPropertyValues(String key) {
        return (List<String>) properties.get(key);
    }

    /**
     * Returns all properties of the resource. Properties are stored as key (String) -> values
     * (List) pairs. It is not recommended to use this method to access properties. Instead, use
     * other property related Resource API methods provided.
     *

     * Note that these values are read-only. Changes made to these values will not be persisted on
     * putting the resource.
     *
     * @return All properties of the resource.
     */
    public Properties getProperties() {

        return properties;
    }

    /**
     * Remove property.
     *
     * @param key the property key.
     */
    public void removeProperty(String key) {

        removePropertyWithNoUpdate(key);
        setPropertiesModified(true);
    }

    /**
     * Remove property without modifiying the resource.
     *
     * @param key the property key.
     */
    public void removePropertyWithNoUpdate(String key) {
        if (key != null) {
            properties.remove(key);
        }
    }

    /**
     * Remove property value.
     *
     * @param key   the property key.
     * @param value the property value.
     */
    public void removePropertyValue(String key, String value) {

        List<String> propValues = getPropertyValues(key);

        if (propValues != null) {
            propValues.remove(value);
            setPropertiesModified(true);
        }
    }

    /**
     * Edit property value.
     *
     * @param key      the key.
     * @param oldValue the old value.
     * @param newValue the new value.
     */
    public void editPropertyValue(String key, String oldValue, String newValue) {

        List<String> propValues = getPropertyValues(key);

        if (propValues != null) {
            propValues.remove(oldValue);
            propValues.add(newValue);
            setPropertiesModified(true);
        }
    }

    /**
     * Set a property with single value.
     *
     * @param key   the property key.
     * @param value the property value.
     */
    public void setProperty(String key, String value) {
        List<String> propValues = new ArrayList<String>();
        propValues.add(value);
        properties.put(key, propValues);
    }

    /**
     * Set a property with multiple value.
     *
     * @param key   the property key.
     * @param value the property values.
     */
    public void setProperty(String key, List<String> value) {
        setPropertyWithNoUpdate(key, value);

        setPropertiesModified(true);
    }

    /**
     * Set a property with multiple value.
     *
     * @param key   the property key.
     * @param value the property values.
     */
    private void setPropertyWithNoUpdate(String key, List<String> value) {
        properties.put(key, value);
    }

    /**
     * Add a property value for the provided key. If there are values associated with the key, this
     * will add append value. If not this will create a new property value for the key.
     *
     * @param key   the property key.
     * @param value the property value.
     */
    public void addProperty(String key, String value) {
        addPropertyWithNoUpdate(key, value);

        setPropertiesModified(true);
    }

    /**
     * Add a property value for the provided key. If there are values associated with the key, this
     * will add append value. If not this will create a new property value for the key. Here the
     * resource modified flag is not set.
     *
     * @param key   the property key.
     * @param value the property value.
     */
    public void addPropertyWithNoUpdate(String key, String value) {
        List<String> propValues = getPropertyValues(key);
        if (propValues != null) {
            // no need to check if the value is already there. we should permit adding repeating
            // values
            propValues.add(value);
        } else {
            propValues = new ArrayList<String>();
            propValues.add(value);
            setPropertyWithNoUpdate(key, propValues);
        }
    }

    /**
     * Set properties.
     *
     * @param properties the properties.
     */
    public void setProperties(Properties properties) {
        if (properties != null) {
            this.properties = properties;
        }

        setPropertiesModified(true);
    }

    /**
     * Method to get the db id of the content
     *
     * @return the db content id.
     */
    public int getDbBasedContentID() {
        return dbBasedContentID;
    }

    /**
     * Method to set the db id of the content.
     *
     * @param dbBasedContentID the db id of the content.
     */
    public void setDbBasedContentID(int dbBasedContentID) {
        this.dbBasedContentID = dbBasedContentID;
    }

    /**
     * A method to retrieve content from the original resource.
     * @throws RegistryException if the operation failed.
     */
    protected void pullContentFromOriginal() throws RegistryException {
        if (content == null && original != null) {
            // if the content is not yet available, try to obtain it from the original resource.
            content = original.getContent();
        }
    }

    /**
     * Method to get the content stream.
     *
     * @return the content stream.
     * @throws RegistryException throws if the operation fail.
     */
    public InputStream getContentStream() throws RegistryException {

        pullContentFromOriginal();
        if (content == null) {
            throw new RegistryException("Resource content is empty.");
        }

        if (content instanceof byte[]) {
            return new ByteArrayInputStream((byte[]) content);

        } else if (content instanceof String) {
            byte[] contentBytes = RegistryUtils.encodeString(((String) content));
            return new ByteArrayInputStream(contentBytes);

        } else if (content instanceof InputStream) {
            return (InputStream) content;

        } else {
            throw new RegistryException(
                    "Cannot return input stream for content of type: " +
                            content.getClass().getName());
        }
    }

    /**
     * Invalidates the current file based content and creates a new file based content for the new
     * content stream. Given content stream will be closed after completing this method.
     *
     * @param contentStream input stream containing the new content
     *
     * @throws RegistryException throws if the operation fail.
     */
    public void setContentStream(InputStream contentStream) throws RegistryException {

        setContentStreamWithNoUpdate(contentStream);

        setContentModified(true);
    }

    /**
     * Invalidates the current file based content and creates a new file based content for the new
     * content stream. Given content stream will be closed after completing this method. Here the
     * resource modified flag is not set.
     *
     * @param contentStream input stream containing the new content
     *
     * @throws RegistryException throws if the operation fail.
     */
    public void setContentStreamWithNoUpdate(InputStream contentStream) throws RegistryException {

        content = RegistryUtils.getByteArray(contentStream);
    }

    /**
     * Method to get the content of the resource. If the resource is a collection this will return
     * an array of string that represent the paths of its children, otherwise it returns an byte
     * array or a string from the default resource implementation.
     *
     * @return the content.
     * @throws RegistryException throws if the operation fail.
     */
    public Object getContent() throws RegistryException {
        pullContentFromOriginal();
        return content;
    }

    /**
     * Set the content of the resource.
     *
     * @param content the resource.
     *
     * @throws RegistryException throws if the operation fail.
     */
    public void setContent(Object content) throws RegistryException {

        setContentWithNoUpdate(content);

        setContentModified(true);
    }

    /**
     * Set the content of the resource without setting the modified flag.
     *
     * @param content the resource.
     *
     * @throws RegistryException throws if the operation fail.
     */
    public void setContentWithNoUpdate(Object content) throws RegistryException {

        this.content = content;
    }

    /**
     * Prepare the resource content to be put.
     *
     * @throws RegistryException throws if the operation fail.
     */
    public void prepareContentForPut() throws RegistryException {

        if (content instanceof String) {
            content = RegistryUtils.encodeString((String) content);
        } else if (content instanceof InputStream) {
            content = RegistryUtils.getByteArray((InputStream) content);
        }
    }

    /**
     * Format the path to the standard way.
     *
     * @param path the path.
     *
     * @return the formatted path.
     */
    private String preparePath(String path) {

        String preparedPath = path;

        // make sure that the path does not end with a "/"
        if (!path.equals(RegistryConstants.ROOT_PATH) &&
                path.endsWith(RegistryConstants.PATH_SEPARATOR)) {
            preparedPath =
                    path.substring(0, path.length() - RegistryConstants.PATH_SEPARATOR.length());
        }

        return preparedPath;
    }

    /**
     * Method to get the last updated user name.
     *
     * @return the last updated user name.
     */
    public String getLastUpdaterUserName() {
        return lastUpdaterUserName;
    }

    /**
     * Method to set the last updater user name.
     *
     * @param lastUpdaterUserName the last updater user name.
     */
    public void setLastUpdaterUserName(String lastUpdaterUserName) {
        this.lastUpdaterUserName = lastUpdaterUserName;
    }

    /**
     * Method to check if the content is modified.
     *
     * @return true, if it is modified, false otherwise.
     */
    public boolean isContentModified() {
        return contentModified;
    }

    /**
     * This method is used to explicitly set the content modified state of the resource. Normal
     * users of the Registry API should not call this method.
     *
     * @param contentModified true if we want to add a new version upon putting this to the
     *                        registry. false otherwise.
     */
    public void setContentModified(boolean contentModified) {
        this.contentModified = contentModified;
        setLastModified(new Date());
        versionableChange = true;
    }

    /**
     * Method to check whether the properties are modified.
     *
     * @return true if the properties modified, false otherwise.
     */
    @SuppressWarnings("unused")
    public boolean isPropertiesModified() {
        return propertiesModified;
    }

    /**
     * Method to set the whether properties are modified.
     *
     * @param propertiesModified whether the properties modified or not.
     */
    public void setPropertiesModified(boolean propertiesModified) {
        this.propertiesModified = propertiesModified;
        setLastModified(new Date());
        versionableChange = true;
    }

    /**
     * Make the properties modified flag true, without changing the last updated time.
     *
     * @param propertiesModified whether the properties modified or not.
     */
    @SuppressWarnings("unused")
    public void setPropertiesModifiedWithNoUpdate(boolean propertiesModified) {
        this.propertiesModified = propertiesModified;
    }

    /**
     * Check whether there are any changes that need to make a version
     *
     * @return true, if there are version-able changes, false otherwise.
     */
    public boolean isVersionableChange() {
        return versionableChange;
    }

    /**
     * Method to set whether there are any changes that need to make a version
     *
     * @param versionableChange whether version-able change is made or not.
     */
    public void setVersionableChange(boolean versionableChange) {
        setLastModified(new Date());
        this.versionableChange = versionableChange;
    }

    /**
     * Get the aspects associated with the resource.
     *
     * @return an array of associated aspects.
     */
    public List<String> getAspects() {
        return getPropertyValues(Aspect.AVAILABLE_ASPECTS);
    }

    /**
     * Method to add an aspect.
     *
     * @param name the name of the aspect.
     */
    public void addAspect(String name) {
        List<String> aspects = getPropertyValues(Aspect.AVAILABLE_ASPECTS);
        if (aspects == null) {
            aspects = new ArrayList<String>();
        }
        aspects.add(name);
        setProperty(Aspect.AVAILABLE_ASPECTS, aspects);
    }

    /**
     * Method to remove an aspect.
     *
     * @param name the name of the aspect to remove.
     */
    public void removeAspect(String name) {
        List<String> aspects = getPropertyValues(Aspect.AVAILABLE_ASPECTS);
        if (aspects != null) {
            aspects.remove(name);
        }
    }

    /**
     * Method to discard the resource
     */
    public void discard() {

    }

    /**
     * Set the session information.
     */
    protected void setSessionInformation() {
        CurrentSession.setUser(userName);
        CurrentSession.setUserRealm(userRealm);
        CurrentSession.setTenantId(tenantId);
    }

    /**
     * UnSet the session information.
     */
    protected void clearSessionInformation() {
        CurrentSession.removeUser();
        CurrentSession.removeUserRealm();
        CurrentSession.removeTenantId();
    }

    /**
     * Get the path id.
     *
     * @return the path id.
     */
    public int getPathID() {
        return pathID;
    }

    /**
     * Set path id.
     *
     * @param pathID the path id.
     */
    public void setPathID(int pathID) {
        this.pathID = pathID;
    }

    /**
     * Get the resource name.
     *
     * @return the resource name.
     */
    public String getName() {
        return name;
    }

    /**
     * Method to set the name.
     *
     * @param name the name.
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Get the resource id implementation instance.
     *
     * @return the resource id.
     */
    public ResourceIDImpl getResourceIDImpl() {
        ResourceIDImpl resourceIDImpl = new ResourceIDImpl();
        resourceIDImpl.setCollection(this instanceof CollectionImpl);
        resourceIDImpl.setPathID(pathID);
        if (name == null && !(this instanceof CollectionImpl)) {
            name = RegistryUtils.getResourceName(path);
        }
        resourceIDImpl.setName(name);
        resourceIDImpl.setPath(path);

        return resourceIDImpl;
    }

    /**
     * Method to get the resource data object.
     *
     * @return the resource data object.
     */
    public ResourceDO getResourceDO() {
        ResourceDO resourceDO = new ResourceDO();
        resourceDO.setPathID(this.getPathID());
        resourceDO.setName(this.name);
        resourceDO.setVersion(this.versionNumber);
        resourceDO.setMediaType(this.mediaType);
        resourceDO.setAuthor(this.authorUserName);
        resourceDO.setCreatedOn(this.createdTime);
        resourceDO.setLastUpdater(this.lastUpdaterUserName);
        resourceDO.setLastUpdatedOn(this.lastModified);
        resourceDO.setDescription(this.description);
        resourceDO.setContentID(this.dbBasedContentID);
        resourceDO.setUUID(this.uuid);
        return resourceDO;
    }

    /**
     * Create a shallow copy of the resource.
     *
     * @return the new resource with a shallow copy of the current resource.
     * @throws RegistryException throws if the operation fail.
     */
    public ResourceImpl getShallowCopy() throws RegistryException {
        ResourceImpl newResource = new ResourceImpl();
        fillResourceCopy(newResource);

        return newResource;
    }

    /**
     * Fill the resource.
     *
     * @param resource the resource to be filled.
     *
     * @return the filled resource
     * @throws RegistryException throws if the operation fail.
     */
    protected ResourceImpl fillResourceCopy(ResourceImpl resource) throws RegistryException {
        resource.setId(this.id);
        resource.setSnapshotID(this.snapshotID);
        resource.setVersionNumber(this.versionNumber);
        resource.setAuthorUserName(this.authorUserName);
        resource.setCreatedTime(new Date(this.createdTime));
        resource.setDescription(this.description);
        resource.setPath(this.path);
        resource.setMatchingSnapshotID(this.matchingSnapshotID);
        resource.setMediaType(this.mediaType);
        resource.setParentPath(this.parentPath);
        resource.setContentModified(this.contentModified);
        resource.setPropertiesModified(this.propertiesModified);
        resource.setVersionableChange(this.versionableChange);
        resource.setState(this.state);
        resource.setProperties(this.properties);
        resource.setDbBasedContentID(dbBasedContentID);
        pullContentFromOriginal();
        if (this.content != null) {
            resource.setContent(this.content);
        }
        resource.setDataAccessManager(this.dataAccessManager);
        resource.setUserName(this.userName);
        resource.setTenantId(this.tenantId);
        resource.setUserRealm(this.userRealm);
        resource.setPathID(this.pathID);
        resource.setName(this.name);
        resource.setUUID(this.uuid);

        // having these two fields at the end is a must, as above field have an affect of them
        resource.setLastUpdaterUserName(this.lastUpdaterUserName);
        resource.setLastModified(new Date(this.lastModified));

        return resource;
    }
}

redpajama_set_name: RedPajamaGithub


text:
package org.apache.nifi.cluster.coordination.http.endpoints;

import org.apache.nifi.cluster.coordination.http.EndpointResponseMerger;
import org.apache.nifi.cluster.manager.NodeResponse;
import org.apache.nifi.cluster.protocol.NodeIdentifier;
import org.apache.nifi.util.FormatUtils;
import org.apache.nifi.web.api.dto.provenance.ProvenanceDTO;
import org.apache.nifi.web.api.dto.provenance.ProvenanceEventDTO;
import org.apache.nifi.web.api.dto.provenance.ProvenanceRequestDTO;
import org.apache.nifi.web.api.dto.provenance.ProvenanceResultsDTO;
import org.apache.nifi.web.api.entity.ProvenanceEntity;

import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

public class ProvenanceQueryEndpointMerger implements EndpointResponseMerger {
    public static final String PROVENANCE_URI = "/nifi-api/provenance";
    public static final Pattern PROVENANCE_QUERY_URI = Pattern.compile("/nifi-api/provenance/[a-f0-9\\-]{36}");

    @Override
    public boolean canHandle(URI uri, String method) {
        if ("POST".equalsIgnoreCase(method) && PROVENANCE_URI.equals(uri.getPath())) {
            return true;
        } else if ("GET".equalsIgnoreCase(method) && PROVENANCE_QUERY_URI.matcher(uri.getPath()).matches()) {
            return true;
        }
        return false;
    }

    @Override
    public NodeResponse merge(URI uri, String method, Set<NodeResponse> successfulResponses, Set<NodeResponse> problematicResponses, NodeResponse clientResponse) {
        if (!canHandle(uri, method)) {
            throw new IllegalArgumentException("Cannot use Endpoint Mapper of type " + getClass().getSimpleName() + " to map responses for URI " + uri + ", HTTP Method " + method);
        }

        final ProvenanceEntity responseEntity = clientResponse.getClientResponse().readEntity(ProvenanceEntity.class);
        final ProvenanceDTO dto = responseEntity.getProvenance();

        final Map<NodeIdentifier, ProvenanceDTO> dtoMap = new HashMap<>();
        for (final NodeResponse nodeResponse : successfulResponses) {
            final ProvenanceEntity nodeResponseEntity = nodeResponse == clientResponse ? responseEntity : nodeResponse.getClientResponse().readEntity(ProvenanceEntity.class);
            final ProvenanceDTO nodeDto = nodeResponseEntity.getProvenance();
            dtoMap.put(nodeResponse.getNodeId(), nodeDto);
        }

        mergeResponses(dto, dtoMap, successfulResponses, problematicResponses);
        return new NodeResponse(clientResponse, responseEntity);
    }

    protected void mergeResponses(ProvenanceDTO clientDto, Map<NodeIdentifier, ProvenanceDTO> dtoMap, Set<NodeResponse> successfulResponses, Set<NodeResponse> problematicResponses) {
        final ProvenanceResultsDTO results = clientDto.getResults();
        final ProvenanceRequestDTO request = clientDto.getRequest();
        final List<ProvenanceEventDTO> allResults = new ArrayList<>(1024);

        final Set<String> errors = new HashSet<>();
        Date oldestEventDate = new Date();
        int percentageComplete = 0;
        boolean finished = true;

        long totalRecords = 0;
        for (final Map.Entry<NodeIdentifier, ProvenanceDTO> entry : dtoMap.entrySet()) {
            final NodeIdentifier nodeIdentifier = entry.getKey();
            final String nodeAddress = nodeIdentifier.getApiAddress() + ":" + nodeIdentifier.getApiPort();

            final ProvenanceDTO nodeDto = entry.getValue();
            final ProvenanceResultsDTO nodeResultDto = nodeDto.getResults();
            if (nodeResultDto != null && nodeResultDto.getProvenanceEvents() != null) {
                // increment the total number of records
                totalRecords += nodeResultDto.getTotalCount();

                // populate the cluster identifier
                for (final ProvenanceEventDTO eventDto : nodeResultDto.getProvenanceEvents()) {
                    // if the cluster node id or node address is not set, then we need to populate them. If they
                    // are already set, we don't want to populate them because it will be the case that they were populated
                    // by the Cluster Coordinator when it federated the request, and we are now just receiving the response
                    // from the Cluster Coordinator.
                    if (eventDto.getClusterNodeId() == null || eventDto.getClusterNodeAddress() == null) {
                        eventDto.setClusterNodeId(nodeIdentifier.getId());
                        eventDto.setClusterNodeAddress(nodeAddress);
                        // add node identifier to the event's id so that it is unique across cluster
                        eventDto.setId(nodeIdentifier.getId() + eventDto.getId());
                    }

                    allResults.add(eventDto);
                }
            }

            if (nodeResultDto.getOldestEvent() != null && nodeResultDto.getOldestEvent().before(oldestEventDate)) {
                oldestEventDate = nodeResultDto.getOldestEvent();
            }

            if (nodeResultDto.getErrors() != null) {
                for (final String error : nodeResultDto.getErrors()) {
                    errors.add(nodeAddress + " -- " + error);
                }
            }

            percentageComplete += nodeDto.getPercentCompleted();
            if (!nodeDto.isFinished()) {
                finished = false;
            }
        }
        percentageComplete /= dtoMap.size();

        // consider any problematic responses as errors
        for (final NodeResponse problematicResponse : problematicResponses) {
            final NodeIdentifier problemNode = problematicResponse.getNodeId();
            final String problemNodeAddress = problemNode.getApiAddress() + ":" + problemNode.getApiPort();
            errors.add(String.format("%s -- Request did not complete successfully (Status code: %s)", problemNodeAddress, problematicResponse.getStatus()));
        }

        // Since we get back up to the maximum number of results from each node, we need to sort those values and then
        // grab only the first X number of them. We do a sort based on time, such that the newest are included.
        // If 2 events have the same timestamp, we do a secondary sort based on Cluster Node Identifier. If those are
        // equal, we perform a tertiary sort based on the the event id
        Collections.sort(allResults, new Comparator<ProvenanceEventDTO>() {
            @Override
            public int compare(final ProvenanceEventDTO o1, final ProvenanceEventDTO o2) {
                final int eventTimeComparison = o1.getEventTime().compareTo(o2.getEventTime());
                if (eventTimeComparison != 0) {
                    return -eventTimeComparison;
                }

                final String nodeId1 = o1.getClusterNodeId();
                final String nodeId2 = o2.getClusterNodeId();
                final int nodeIdComparison;
                if (nodeId1 == null && nodeId2 == null) {
                    nodeIdComparison = 0;
                } else if (nodeId1 == null) {
                    nodeIdComparison = 1;
                } else if (nodeId2 == null) {
                    nodeIdComparison = -1;
                } else {
                    nodeIdComparison = -nodeId1.compareTo(nodeId2);
                }

                if (nodeIdComparison != 0) {
                    return nodeIdComparison;
                }

                return -Long.compare(o1.getEventId(), o2.getEventId());
            }
        });

        final int maxResults = request.getMaxResults().intValue();
        final List<ProvenanceEventDTO> selectedResults;
        if (allResults.size() < maxResults) {
            selectedResults = allResults;
        } else {
            selectedResults = allResults.subList(0, maxResults);
        }

        // include any errors
        if (errors.size() > 0) {
            results.setErrors(errors);
        }

        if (clientDto.getRequest().getMaxResults() != null && totalRecords >= clientDto.getRequest().getMaxResults()) {
            results.setTotalCount(clientDto.getRequest().getMaxResults().longValue());
            results.setTotal(FormatUtils.formatCount(clientDto.getRequest().getMaxResults().longValue()) + "+");
        } else {
            results.setTotal(FormatUtils.formatCount(totalRecords));
            results.setTotalCount(totalRecords);
        }

        results.setProvenanceEvents(selectedResults);
        results.setOldestEvent(oldestEventDate);
        results.setGenerated(new Date());
        clientDto.setPercentCompleted(percentageComplete);
        clientDto.setFinished(finished);
    }
}


text:
napalm-ios dependencies
=======================

Ubuntu and Debian
-----------------

.. code-block:: bash

  sudo apt-get install -y --force-yes libssl-dev libffi-dev python-dev python-cffi

RedHat and CentOS
-----------------

.. code-block:: bash

    sudo yum install -y python-pip gcc openssl openssl-devel libffi-devel python-devel

FreeBSD
-------

.. code-block:: bash

    sudo pkg_add -r py27-pip


text:
Connected social accounts

Connect other social accounts


text:
package core

import (
	"log"
	"net/http"
	"os"
	"strconv"
)

// Application represents an application.
type Application struct {
	preHandlers      []Handler
	routes           []*route
	postHandlers     []Handler
	notFoundHandlers []Handler
	Logger           *log.Logger
	errorHandler     ErrorHandler
	*dataContainer
}

// UsePre adds pre handlers to the application.
func (app *Application) UsePre(handlers ...Handler) {
	app.preHandlers = append(app.preHandlers, handlers...)
}

// UsePost adds post handlers to the application.
func (app *Application) UsePost(handlers ...Handler) {
	app.postHandlers = append(app.postHandlers, handlers...)
}

// ServeHTTP is an HTTP entry point for the application.
func (app *Application) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
	res := newResponse(rw)

	ctx := newContext(app, res, req)

	if err := ctx.handle(); err != nil {
		app.errorHandler(ctx, err)
	}
}

// Run runs an HTTP server.
func (app *Application) Run(addr string) {
	app.Logger.Printf(" Listening on %s", addr)
	app.Logger.Fatal(http.ListenAndServe(addr, app))
}

// Get adds a route with GET method.
func (app *Application) Get(pattern string, handlers ...Handler) {
	app.routes = append(app.routes, newRoute(MethodGET, pattern, handlers))
}

// Patch adds a route with PATCH method.
func (app *Application) Patch(pattern string, handlers ...Handler) {
	app.routes = append(app.routes, newRoute(MethodPATCH, pattern, handlers))
}

// Post adds a route with POST method.
func (app *Application) Post(pattern string, handlers ...Handler) {
	app.routes = append(app.routes, newRoute(MethodPOST, pattern, handlers))
}

// Put adds a route with PUT method.
func (app *Application) Put(pattern string, handlers ...Handler) {
	app.routes = append(app.routes, newRoute(MethodPUT, pattern, handlers))
}

// Delete adds a route with DELETE method.
func (app *Application) Delete(pattern string, handlers ...Handler) {
	app.routes = append(app.routes, newRoute(MethodDELETE, pattern, handlers))
}

// Options adds a route with OPTIONS method.
func (app *Application) Options(pattern string, handlers ...Handler) {
	app.routes = append(app.routes, newRoute(MethodOPTIONS, pattern, handlers))
}

// Head adds a route with HEAD method.
func (app *Application) Head(pattern string, handlers ...Handler) {
	app.routes = append(app.routes, newRoute(MethodHEAD, pattern, handlers))
}

// Any adds a route goes with any methods.
func (app *Application) Any(pattern string, handlers ...Handler) {
	app.routes = append(app.routes, newRoute(MethodANY, pattern, handlers))
}

// NotFound sets not found handlers to the application.
func (app *Application) NotFound(handlers ...Handler) {
	app.notFoundHandlers = handlers
}

// SetErrorHandler sets the handler to the application.
func (app *Application) SetErrorHandler(handler ErrorHandler) {
	app.errorHandler = handler
}

// NewApplication generates an application and returns it.
func NewApplication() *Application {
	return &Application{
		notFoundHandlers: []Handler{notFound},
		Logger:           log.New(os.Stdout, loggerPrefix, 0),
		dataContainer: &dataContainer{
			data: map[interface{}]interface{}{},
		},
		errorHandler: errorHandler,
	}
}

// notFoundCheck provides a handler which checkes if not found handlers should be invoked or not.
func notFoundCheck(ctx *Context) error {
	if ctx.Res.Status() != 0 {
		return nil
	}

	return ctx.Next()
}

// notFound provides a default not found handler.
func notFound(ctx *Context) error {
	http.NotFound(ctx.Res, ctx.Req)

	return nil
}

// errorHandler provides a default error handler.
func errorHandler(ctx *Context, err error) {
	ctx.App.Logger.Printf("[ErrorHandler] An error occurred: %+v", err)

	if ctx.Res.Status() == 0 {
		http.Error(ctx.Res, strconv.Itoa(http.StatusInternalServerError)+" "+http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
	}
}


text:
// Type definitions for queue
// Project: @terascope/teraslice-op-test-harness

import {
    ReaderModule,
    LegacyProcessor,
    ProcessorModule,
    OpConfig,
    ExecutionConfig,
    TestClientConfig,
    SliceRequest,
    SliceResult,
    ProcessorFn,
    CoreOperation,
    LegacyReader,
    DataEntity,
    Slice,
    TestContext,
    TestClients,
    DataInput,
} from '@terascope/job-components';
import { EventEmitter } from 'events';

export = opTestHarness;

declare function opTestHarness(op: opTestHarness.OpTestHarnessInput): opTestHarness.TestHarness;

declare namespace opTestHarness {
    export type OpTestHarnessInput = ProcessorModule|ReaderModule|LegacyProcessor|LegacyReader;
    export type OpType = 'slicer'|'reader'|'processor';
    export interface InitOptions {
        opConfig?: OpConfig;
        executionConfig?: ExecutionConfig;
        retryData?: object[];
        clients?: TestClientConfig[];
        type: OpType;
    }
    export type LegacyRunResult = any;

    export interface SampleData {
        ip: string;
        userAgent: string;
        url: string;
        uuid: string;
        created: string;
        ipv6: string;
        location: string;
        bytes: number;
    }

    export interface SampleDataElasticsearch {
        took: number;
        timed_out: boolean;
        hits: Hits;
        _shards: Shards;
    }

    interface Shards {
        total: number;
        successful: number;
        failed: number;
    }

    interface Hits {
        total: number;
        max_score: number;
        hits: Hit[];
    }

    interface Hit {
        _index: string;
        _type: string;
        _id: string;
        _score: number;
        _source: SampleData;
    }

    export interface SimpleData {
        name: string;
        age: number;
    }

    export interface SampleData {
        simple: SimpleData[];
        arrayLike: SampleData[];
        esLike: SampleDataElasticsearch;
    }

    export interface TestHarness<T = any> {
        fakeLogger: Logger;
        schema: any;
        process: ProcessorFn<T>;
        context: TestContext;
        data: SampleData;
        logger: Logger;
        events: EventEmitter;
        operationFn: OpTestHarnessInput;
        opConfig: OpConfig;
        executionConfig: ExecutionConfig;
        retryData?: object[];
        clientList: TestClients;

        /**
         * Initialize and run an operation
        */
        processData(opConfig: OpConfig, data: DataInput[]): Promise<RunResult>;

        /**
         * Set the clients on the context
        */
        setClients(clients?: TestClientConfig[]): void;

        /**
         * Initialize the Processor or Reader
         * @returns an Operation
        */
        init(options: InitOptions): Promise<OperationTester>;

        /**
         * @deprecated
        */
        run(data: any, extraOpConfig?: object, extraContext?: object): LegacyRunResult;

        /**
         * @deprecated
        */
        runAsync(data: any, extraOpConfig?: object, extraContext?: object): Promise<LegacyRunResult>;

        /**
         * @deprecated
        */
        runSlices(slices: SliceRequest[], extraOpConfig?: object, extraContext?: object): Promise<SliceResult[]>;

        /**
         * @deprecated
        */
        getProcessor(opConfig: OpConfig, extraContext?: object): LegacyProcessor;

        /**
         * @deprecated
        */
        processFn(myProcessor: ProcessorFn<T>, data: any): any;

        /**
         * @deprecated
        */
        emulateShutdown(): void;

        /**
         * @deprecated
        */
        runProcessorSpecs(processor: LegacyProcessor): void;
    }

    export type RunResult = DataEntity[]|Slice[]|SliceRequest[];

    export interface SlicerRunInput {
        fullResponse?: boolean;
    }

    export type RunInput = SlicerRunInput|DataInput[];

    export interface OperationTester {
        operation: CoreOperation;
        isReader: boolean;
        isSlicer: boolean;
        isProcessor: boolean;
        context: TestContext;
        logger: Logger;
        operationFn: OpTestHarnessInput;
        opConfig: OpConfig;
        executionConfig: ExecutionConfig;
        retryData?: object[];

        init(): Promise<OperationTester>;

        run(data: RunInput): Promise<RunResult>;
    }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <include layout="@layout/title_view" />

    <TextView
        android:id="@+id/textView1"
        style="@style/account_more_list_text"
        android:text="@string/setting" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/list_item_divide_operate" />

    <TextView
        android:id="@+id/textView1"
        style="@style/account_more_list_text"
        android:text="@string/feedback" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/list_item_divide_operate" />

    <TextView
        android:id="@+id/textView1"
        style="@style/account_more_list_text"
        android:text="@string/help" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/list_item_divide_operate" />

    <TextView
        android:id="@+id/textView1"
        style="@style/account_more_list_text"
        android:text="@string/about" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/list_item_divide_operate" />
</LinearLayout>


text:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Cosmos.IL2CPU;
using Cosmos.IL2CPU.Plugs;
using SR = System.Reflection;
using Cosmos.Assembler;
using System.Reflection.Emit;
using _MemberInfo = System.Runtime.InteropServices._MemberInfo;
using SysReflection = System.Reflection;

namespace Cosmos.IL2CPU
{
    public class PlugManager
    {
        public bool ThrowExceptions = true;

        public LogExceptionDelegate LogException = null;

        public delegate void ScanMethodDelegate(MethodBase aMethod, bool aIsPlug, string sourceItem);
        public ScanMethodDelegate ScanMethod = null;
        public delegate void QueueDelegate(_MemberInfo aItem, object aSrc, string aSrcType, string sourceItem = null);
        public QueueDelegate Queue = null;

        // Contains a list of plug implementor classes
        // Key = Target Class
        // Value = List of Implementors. There may be more than one
        protected Dictionary<Type, List<Type>> mPlugImpls = new Dictionary<Type, List<Type>>();
        // List of inheritable plugs. Plugs that start at an ancestor and plug all
        // descendants. For example, delegates
        protected Dictionary<Type, List<Type>> mPlugImplsInhrt = new Dictionary<Type, List<Type>>();
        // list of field plugs
        protected IDictionary<Type, IDictionary<string, PlugFieldAttribute>> mPlugFields = new Dictionary<Type, IDictionary<string, PlugFieldAttribute>>();

        public Dictionary<Type, List<Type>> PlugImpls
        {
            get
            {
                return mPlugImpls;
            }
        }
        public Dictionary<Type, List<Type>> PlugImplsInhrt
        {
            get
            {
                return mPlugImplsInhrt;
            }
        }
        public IDictionary<Type, IDictionary<string, PlugFieldAttribute>> PlugFields
        {
            get
            {
                return mPlugFields;
            }
        }

        private Orvid.Collections.SkipList ResolvedPlugs = new Orvid.Collections.SkipList();
        private static string BuildMethodKeyName(MethodBase m)
        {
            return LabelName.GenerateFullName(m);
        }

        public PlugManager(LogExceptionDelegate aLogException)
        {
            LogException = aLogException;
        }
        public PlugManager(LogExceptionDelegate aLogException, ScanMethodDelegate aScanMethod, QueueDelegate aQueueMethod)
        {
            LogException = aLogException;
            ScanMethod = aScanMethod;
            Queue = aQueueMethod;
        }

        public void FindPlugImpls()
        {
            // TODO: Cache method list with info - so we dont have to keep
            // scanning attributes for enabled etc repeatedly
            // TODO: New plug system, common plug base which all descend from
            // It can have a "this" member and then we
            // can separate static from instance by the static keyword
            // and ctors can be static "ctor" by name
            // Will still need plug attrib though to specify target
            // Also need to handle asm plugs, but those will be different anyways
            // TODO: Allow whole class plugs? ie, a class that completely replaces another class
            // and is substituted on the fly? Plug scanner would direct all access to that
            // class and throw an exception if any method, field, member etc is missing.
            foreach (var xAsm in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (!xAsm.GlobalAssemblyCache)
                {
                    //if (xAsm.GetName().Name == "Cosmos.IL2CPU.X86") {
                    //  // skip this assembly for now. at the moment we introduced the AssemblerMethod.AssembleNew method, for allowing those to work
                    //  // with the Cosmos.IL2CPU* stack, we found we could not use the Cosmos.IL2CPU.X86 plugs, as they contained some AssemblerMethods.
                    //  // This would result in a circular reference, thus we copied them to a new assembly. While the Cosmos.IL2CPU.X86 assembly is being
                    //  // referenced, we need to skip it here.
                    //  continue;
                    //}
                    // Find all classes marked as a Plug
                    foreach (var xPlugType in xAsm.GetTypes())
                    {
                        // Foreach, it is possible there could be one plug class with mult plug targets
                        foreach (PlugAttribute xAttrib in xPlugType.GetCustomAttributes(typeof(PlugAttribute), false))
                        {
                            var xTargetType = xAttrib.Target;
                            // If no type is specified, try to find by a specified name.
                            // This is needed in cross assembly references where the
                            // plug cannot reference the assembly of the target type
                            if (xTargetType == null)
                            {
                                try
                                {
                                    xTargetType = Type.GetType(xAttrib.TargetName, true, false);
                                }
                                catch (Exception ex)
                                {
                                    throw new Exception("Error", ex);
                                }
                            }
                            // Only keep this plug if its for MS.NET.
                            // TODO: Integrate with builder options to allow Mono support again.
                            if (!xAttrib.IsMonoOnly)
                            {
                                var mPlugs = xAttrib.Inheritable ? mPlugImplsInhrt : mPlugImpls;
                                List<Type> xImpls;
                                if (mPlugs.TryGetValue(xTargetType, out xImpls))
                                {
                                    xImpls.Add(xPlugType);
                                }
                                else
                                {
                                    xImpls = new List<Type>();
                                    xImpls.Add(xPlugType);
                                    mPlugs.Add(xTargetType, xImpls);
                                }
                            }
                        }
                    }
                }
            }
        }

        public void ScanFoundPlugs()
        {
            ScanPlugs(mPlugImpls);
            ScanPlugs(mPlugImplsInhrt);
        }
        public void ScanPlugs(Dictionary<Type, List<Type>> aPlugs)
        {
            foreach (var xPlug in aPlugs)
            {
                var xImpls = xPlug.Value;
                foreach (var xImpl in xImpls)
                {
                    #region PlugMethods scan

                    foreach (var xMethod in xImpl.GetMethods(BindingFlags.Public | BindingFlags.Static))
                    {
                        PlugMethodAttribute xAttrib = null;
                        foreach (PlugMethodAttribute x in xMethod.GetCustomAttributes(typeof(PlugMethodAttribute), false))
                        {
                            xAttrib = x;
                        }
                        if (xAttrib == null)
                        {
                            //At this point we need to check the plug method actually
                            //matches a method that might need plugging.
                            // x08 bug
                            // We must check for a number of cases:
                            //   - Public, static and private/internal methods that need plugging
                            //   - Ctor or Cctor

                            bool OK = false;
                            if (xMethod.Name.ToLower() == "ctor" ||
                                xMethod.Name.ToLower() == "cctor")
                            {
                                OK = true;
                            }
                            else
                            {
                                //Skip checking methods related to fields because it's just too messy...
                                if (xMethod.GetParameters().Where(delegate (ParameterInfo x)
                                {
                                    return x.GetCustomAttributes(typeof(FieldAccessAttribute)).Count() > 0;
                                }).Count() > 0)
                                {
                                    OK = true;
                                }
                                else
                                {
                                    var xParamTypes = xMethod.GetParameters().Select(delegate (ParameterInfo x)
                                    {
                                        var result = x.ParameterType;
                                        if (result.IsByRef)
                                        {
                                            result = result.GetElementType();
                                        }
                                        else if (result.IsPointer)
                                        {
                                            result = null;
                                        }
                                        return result;
                                    }).ToArray();

                                    var posMethods = xPlug.Key.GetMethods(BindingFlags.Instance | BindingFlags.Static |
                                                                          BindingFlags.NonPublic | BindingFlags.Public)
                                                                          .Where(x => x.Name == xMethod.Name);
                                    foreach (SysReflection.MethodInfo posInf in posMethods)
                                    {
                                        // If static, no this param
                                        // Otherwise, take into account first param is this param
                                        //This param is either of declaring type, or ref to declaring type or pointer
                                        var posMethParamTypes = posInf.GetParameters().Select(delegate (ParameterInfo x)
                                        {
                                            var result = x.ParameterType;
                                            if (result.IsByRef)
                                            {
                                                result = result.GetElementType();
                                            }
                                            else if (result.IsPointer)
                                            {
                                                result = null;
                                            }
                                            return result;
                                        }).ToArray();

                                        if (posInf.IsStatic)
                                        {
                                            if (posMethParamTypes.Length != xParamTypes.Length)
                                            {
                                                continue;
                                            }

                                            OK = true;
                                            // Exact params match excl. pointers - there could be "null" types for statics since some could be pointers
                                            for (int i = 0; i < posMethParamTypes.Length; i++)
                                            {
                                                if ((posMethParamTypes[i] == null && xParamTypes[i] == null) || !posMethParamTypes[i].Equals(xParamTypes[i]))
                                                {
                                                    OK = false;
                                                    break;
                                                }
                                            }

                                            if (!OK)
                                            {
                                                continue;
                                            }
                                            else
                                            {
                                                break;
                                            }
                                        }
                                        else
                                        {
                                            // Exact match except possibly 1st param
                                            if (posMethParamTypes.Length != xParamTypes.Length &&
                                                posMethParamTypes.Length != xParamTypes.Length - 1)
                                            {
                                                continue;
                                            }
                                            int offset = 0;

                                            OK = true;
                                            // Exact match except if first param doesn't match, we skip 1st param and restart matching
                                            for (int i = 0; i < posMethParamTypes.Length && (i + offset) < xParamTypes.Length; i++)
                                            {
                                                //Continue if current type is null i.e. was a pointer as that could be any type originally.
                                                if (xParamTypes[i + offset] != null && !posMethParamTypes[i].Equals(xParamTypes[i + offset]))
                                                {
                                                    if (offset == 0)
                                                    {
                                                        offset = 1;
                                                        i = -1;
                                                    }
                                                    else
                                                    {
                                                        OK = false;
                                                        break;
                                                    }
                                                }
                                            }
                                            if (posMethParamTypes.Length == 0 && xParamTypes.Length > 0)
                                            {
                                                //We use IsAssignableFrom here because _some_ plugs decide to use more generic types for the
                                                //this parameter
                                                OK = xParamTypes[0] == null || xParamTypes[0].IsAssignableFrom(posInf.DeclaringType);
                                            }

                                            if (!OK)
                                            {
                                                continue;
                                            }
                                            else
                                            {
                                                break;
                                            }
                                        }
                                    }
                                }
                            }

                            if (OK)
                            {
                                if (ScanMethod != null)
                                {
                                    ScanMethod(xMethod, true, "Plug Sub Method");
                                }
                            }
                            else
                            {
                                if (LogException != null)
                                {
                                    LogException(new Exception("Invalid plug method! Target method not found. : " + xMethod.GetFullName()));
                                }
                            }
                        }
                        else
                        {
                            if (xAttrib.IsWildcard && xAttrib.Assembler == null)
                            {
                                Exception anEx = new Exception("Wildcard PlugMethods need to use an assembler for now.");
                                if (ThrowExceptions)
                                {
                                    throw anEx;
                                }
                                else
                                {
                                    LogException(anEx);
                                }
                            }
                            if (xAttrib.Enabled && !xAttrib.IsMonoOnly)
                            {
                                if (ScanMethod != null)
                                {
                                    ScanMethod(xMethod, true, ".Net plug Method");
                                }
                            }
                        }
                    }
                    #endregion
                    #region PlugFields scan
                    foreach (var xField in xImpl.GetCustomAttributes(typeof(PlugFieldAttribute), true).Cast<PlugFieldAttribute>())
                    {
                        IDictionary<string, PlugFieldAttribute> xFields = null;
                        if (!mPlugFields.TryGetValue(xPlug.Key, out xFields))
                        {
                            xFields = new Dictionary<string, PlugFieldAttribute>();
                            mPlugFields.Add(xPlug.Key, xFields);
                        }
                        if (xFields.ContainsKey(xField.FieldId))
                        {
                            Exception anEx = new Exception("Duplicate PlugField found for field '" + xField.FieldId + "'!");
                            if (ThrowExceptions)
                            {
                                throw anEx;
                            }
                            else
                            {
                                LogException(anEx);
                            }
                        }
                        xFields.Add(xField.FieldId, xField);
                    }
                    #endregion
                }
            }
        }

        public MethodBase ResolvePlug(Type aTargetType, List<Type> aImpls, MethodBase aMethod, Type[] aParamTypes)
        {
            //TODO: This method is "reversed" from old - remember that when porting
            MethodBase xResult = null;

            // Setup param types for search
            Type[] xParamTypes;
            if (aMethod.IsStatic)
            {
                xParamTypes = aParamTypes;
            }
            else
            {
                // If its an instance method, we have to add this to the ParamTypes to search
                xParamTypes = new Type[aParamTypes.Length + 1];
                if (aParamTypes.Length > 0)
                {
                    aParamTypes.CopyTo(xParamTypes, 1);
                }
                xParamTypes[0] = aTargetType;
            }

            PlugMethodAttribute xAttrib = null;
            foreach (var xImpl in aImpls)
            {
                // TODO: cleanup this loop, next statement shouldnt be neccessary
                if (xResult != null)
                {
                    break;
                }
                // Plugs methods must be static, and public
                // Search for non signature matches first since signature searches are slower
                xResult = xImpl.GetMethod(aMethod.Name, BindingFlags.Static | BindingFlags.Public
                  , null, xParamTypes, null);
                if (xResult == null && aMethod.Name == ".ctor")
                {
                    xResult = xImpl.GetMethod("Ctor", BindingFlags.Static | BindingFlags.Public
                      , null, xParamTypes, null);
                }
                if (xResult == null && aMethod.Name == ".cctor")
                {
                    xResult = xImpl.GetMethod("CCtor", BindingFlags.Static | BindingFlags.Public
                      , null, xParamTypes, null);
                }

                if (xResult == null)
                {
                    // Search by signature
                    foreach (var xSigMethod in xImpl.GetMethods(BindingFlags.Static | BindingFlags.Public))
                    {
                        // TODO: Only allow one, but this code for now takes the last one
                        // if there is more than one
                        xAttrib = null;
                        foreach (PlugMethodAttribute x in xSigMethod.GetCustomAttributes(typeof(PlugMethodAttribute), false))
                        {
                            xAttrib = x;
                        }

                        if (xAttrib != null && (xAttrib.IsWildcard && !xAttrib.WildcardMatchParameters))
                        {
                            MethodBase xTargetMethod = null;
                            if (String.Compare(xSigMethod.Name, "Ctor", true) == 0 ||
                               String.Compare(xSigMethod.Name, "Cctor", true) == 0)
                            {
                                xTargetMethod = aTargetType.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).SingleOrDefault();
                            }
                            else
                            {
                                xTargetMethod = (from item in aTargetType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance)
                                                 where item.Name == xSigMethod.Name
                                                 select item).SingleOrDefault();
                            }
                            if (xTargetMethod == aMethod)
                            {
                                xResult = xSigMethod;
                            }
                        }
                        else
                        {

                            var xParams = xSigMethod.GetParameters();
                            //TODO: Static method plugs dont seem to be separated
                            // from instance ones, so the only way seems to be to try
                            // to match instance first, and if no match try static.
                            // I really don't like this and feel we need to find
                            // an explicit way to determine or mark the method
                            // implementations.
                            //
                            // Plug implementations take "this" as first argument
                            // so when matching we don't include it in the search
                            Type[] xTypesInst = null;
                            var xActualParamCount = xParams.Length;
                            foreach (var xParam in xParams)
                            {
                                if (xParam.GetCustomAttributes(typeof(FieldAccessAttribute), false).Length > 0)
                                {
                                    xActualParamCount--;
                                }
                            }
                            Type[] xTypesStatic = new Type[xActualParamCount];
                            // If 0 params, has to be a static plug so we skip
                            // any copying and leave xTypesInst = null
                            // If 1 params, xTypesInst must be converted to Type[0]
                            if (xActualParamCount == 1)
                            {
                                xTypesInst = new Type[0];

                                var xReplaceType = xParams[0].GetCustomAttributes(typeof(FieldTypeAttribute), false);
                                if (xReplaceType.Length == 1)
                                    xTypesStatic[0] = Type.GetType(((FieldTypeAttribute)xReplaceType[0]).Name, true);
                                else
                                    xTypesStatic[0] = xParams[0].ParameterType;
                            }
                            else if (xActualParamCount > 1)
                            {
                                xTypesInst = new Type[xActualParamCount - 1];
                                var xCurIdx = 0;
                                foreach (var xParam in xParams.Skip(1))
                                {
                                    if (xParam.GetCustomAttributes(typeof(FieldAccessAttribute), false).Length > 0)
                                    {
                                        continue;
                                    }

                                    var xReplaceType = xParam.GetCustomAttributes(typeof(FieldTypeAttribute), false);
                                    if (xReplaceType.Length == 1)
                                        xTypesInst[xCurIdx] = Type.GetType(((FieldTypeAttribute)xReplaceType[0]).Name, true);
                                    else
                                        xTypesInst[xCurIdx] = xParam.ParameterType;

                                    xCurIdx++;
                                }
                                xCurIdx = 0;
                                foreach (var xParam in xParams)
                                {
                                    if (xParam.GetCustomAttributes(typeof(FieldAccessAttribute), false).Length > 0)
                                    {
                                        xCurIdx++;
                                        continue;
                                    }
                                    if (xCurIdx >= xTypesStatic.Length)
                                    {
                                        break;
                                    }
                                    xTypesStatic[xCurIdx] = xParam.ParameterType;
                                    xCurIdx++;
                                }
                            }
                            SysReflection.MethodBase xTargetMethod = null;
                            // TODO: In future make rule that all ctor plugs are called
                            // ctor by name, or use a new attrib
                            //TODO: Document all the plug stuff in a document on website
                            //TODO: To make inclusion of plugs easy, we can make a plugs master
                            // that references the other default plugs so user exes only
                            // need to reference that one.
                            // TODO: Skip FieldAccessAttribute if in impl
                            if (xTypesInst != null)
                            {
                                if (string.Compare(xSigMethod.Name, "ctor", true) == 0)
                                {
                                    xTargetMethod = aTargetType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, CallingConventions.Any, xTypesInst, null);
                                }
                                else
                                {
                                    xTargetMethod = aTargetType.GetMethod(xSigMethod.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, CallingConventions.Any, xTypesInst, null);
                                }
                            }
                            // Not an instance method, try static
                            if (xTargetMethod == null)
                            {
                                if (string.Compare(xSigMethod.Name, "cctor", true) == 0
                                  || string.Compare(xSigMethod.Name, "ctor", true) == 0)
                                {
                                    xTargetMethod = aTargetType.GetConstructor(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, CallingConventions.Any, xTypesStatic, null);
                                }
                                else
                                {
                                    xTargetMethod = aTargetType.GetMethod(xSigMethod.Name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, CallingConventions.Any, xTypesStatic, null);
                                }
                            }
                            if (xTargetMethod == aMethod)
                            {
                                xResult = xSigMethod;
                                break;
                            }
                            if (xAttrib != null && xAttrib.Signature != null)
                            {
                                var xName = DataMember.FilterStringForIncorrectChars(LabelName.GenerateFullName(aMethod));
                                if (string.Compare(xName, xAttrib.Signature, true) == 0)
                                {
                                    xResult = xSigMethod;
                                    break;
                                }
                            }
                            xAttrib = null;
                        }
                    }
                }
                else
                {
                    // check if signatur is equal
                    var xResPara = xResult.GetParameters();
                    var xAMethodPara = aMethod.GetParameters();
                    if (aMethod.IsStatic)
                    {
                        if (xResPara.Length != xAMethodPara.Length)
                            return null;
                    }
                    else
                    {
                        if (xResPara.Length - 1 != xAMethodPara.Length)
                            return null;
                    }
                    for (int i = 0; i < xAMethodPara.Length; i++)
                    {
                        int correctIndex = aMethod.IsStatic ? i : i + 1;
                        if (xResPara[correctIndex].ParameterType != xAMethodPara[i].ParameterType)
                            return null;
                    }
                    if (xResult.Name == "Ctor" && aMethod.Name == ".ctor")
                    {
                    }
                    else if (xResult.Name == "CCtor" && aMethod.Name == ".cctor")
                    {
                    }
                    else if (xResult.Name != aMethod.Name)
                        return null;
                }
            }
            if (xResult == null)
                return null;

            // If we found a matching method, check for attributes
            // that might disable it.
            //TODO: For signature ones, we could cache the attrib. Thats
            // why we check for null here
            if (xAttrib == null)
            {
                // TODO: Only allow one, but this code for now takes the last one
                // if there is more than one
                foreach (PlugMethodAttribute x in xResult.GetCustomAttributes(typeof(PlugMethodAttribute), false))
                {
                    xAttrib = x;
                }
            }

            // See if we need to disable this plug
            if (xAttrib != null)
            {
                if (!xAttrib.Enabled)
                {
                    //xResult = null;
                    return null;
                }
                else if (xAttrib.IsMonoOnly)
                {
                    //TODO: Check this against build options
                    //TODO: Two exclusive IsOnly's dont make sense
                    // refactor these as a positive rather than negative
                    // Same thing at type plug level
                    //xResult = null;
                    return null;
                }
                //else if (xAttrib.Signature != null) {
                //  var xName = DataMember.FilterStringForIncorrectChars(MethodInfoLabelGenerator.GenerateFullName(xResult));
                //  if (string.Compare(xName, xAttrib.Signature, true) != 0) {
                //    xResult = null;
                //  }
                //}
            }

            InlineAttribute xInlineAttrib = null;
            foreach (InlineAttribute inli in xResult.GetCustomAttributes(typeof(InlineAttribute), false))
            {
                xInlineAttrib = inli;
            }

            if (xInlineAttrib == null)
            {
                if (Queue != null)
                {
                    CompilerHelpers.Debug("Queueing Plug:", xResult.DeclaringType, "::", xResult.Name);
                    Queue(xResult, null, "Plug Method");
                }
            }

            //if (xAttrib != null && xAttrib.Signature != null)
            //{
            //    var xTargetMethods = aTargetType.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
            //    //System_Void__Indy_IL2CPU_Assembler_Assembler__cctor__
            //    //If signature exists, the search is slow. Signatures
            //    //are infrequent though, so for now we just go slow method
            //    //and have not optimized or cached this info. When we
            //    //redo the plugs, we can fix this.
            //    bool xEnabled=true;
            //    foreach (var xTargetMethod in xTargetMethods)
            //    {
            //        string sName = DataMember.FilterStringForIncorrectChars(MethodInfoLabelGenerator.GenerateFullName(xTargetMethod));
            //        if (string.Compare(sName, xAttrib.Signature, true) == 0)
            //        {
            //            //uint xUID = QueueMethod(xPlugImpl.Plug, "Plug", xMethod, true);
            //            //mMethodPlugs.Add(xTargetMethod, new PlugInfo(xUID, xAttrib.Assembler));
            //            // Mark as disabled, because we already handled it
            //            xEnabled = false;
            //            break;
            //        }
            //    }
            //    // if still enabled, we didn't find our method
            //    if (xEnabled)
            //    {
            //        // todo: more precise error: imagine having a 100K line project, and this error happens...
            //        throw new Exception("Plug target method not found.");
            //    }
            //}
            return xResult;
        }
        public MethodBase ResolvePlug(MethodBase aMethod, Type[] aParamTypes)
        {
            MethodBase xResult = null;
            var xMethodKey = BuildMethodKeyName(aMethod);
            if (ResolvedPlugs.Contains(xMethodKey, out xResult))
            {
                return xResult;
            }
            else
            {
                // TODO: Right now plugs are compiled in, even if they are not needed.
                // Maybe change this so plugs that are not needed are not compiled in?
                // To do so, maybe plugs could be marked as they are used

                List<Type> xImpls;
                // Check for exact type plugs first, they have precedence
                if (mPlugImpls.TryGetValue(aMethod.DeclaringType, out xImpls))
                {
                    xResult = ResolvePlug(aMethod.DeclaringType, xImpls, aMethod, aParamTypes);
                }

                // Check for inheritable plugs second.
                // We also need to fall through at method level, not just type.
                // That is a exact type plug could exist, but not method match.
                // In such a case the Inheritable methods should still be searched
                // if there is a inheritable type match.
                if (xResult == null)
                {
                    foreach (var xInheritable in mPlugImplsInhrt)
                    {
                        if (aMethod.DeclaringType.IsSubclassOf(xInheritable.Key))
                        {
                            xResult = ResolvePlug(aMethod.DeclaringType/*xInheritable.Key*/, xInheritable.Value, aMethod, aParamTypes);
                            if (xResult != null)
                            {
                                // prevent key overriding.
                                break;
                            }
                        }
                    }
                }

                ResolvedPlugs.Add(xMethodKey, xResult);

                return xResult;
            }
        }

        public void Clean()
        {
            mPlugImpls = new Dictionary<Type, List<Type>>();
            mPlugImplsInhrt = new Dictionary<Type, List<Type>>();
            mPlugFields = new Dictionary<Type, IDictionary<string, PlugFieldAttribute>>();

            ResolvedPlugs = new Orvid.Collections.SkipList();
        }
    }
}