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

package org.apache.tapestry5.internal.plastic;

import org.apache.tapestry5.internal.plastic.asm.AnnotationVisitor;
import org.apache.tapestry5.internal.plastic.asm.Opcodes;
import org.apache.tapestry5.internal.plastic.asm.Type;
import org.apache.tapestry5.internal.plastic.asm.tree.*;
import org.apache.tapestry5.plastic.*;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;

@SuppressWarnings("all")
public class PlasticClassImpl extends Lockable implements PlasticClass, InternalPlasticClassTransformation, Opcodes
{
    private static final String NOTHING_TO_VOID = "()V";

    static final String CONSTRUCTOR_NAME = "<init>";

    private static final String OBJECT_INT_TO_OBJECT = "(Ljava/lang/Object;I)Ljava/lang/Object;";

    private static final String OBJECT_INT_OBJECT_TO_VOID = "(Ljava/lang/Object;ILjava/lang/Object;)V";

    private static final String OBJECT_INT_OBJECT_ARRAY_TO_METHOD_INVOCATION_RESULT = String.format(
            "(Ljava/lang/Object;I[Ljava/lang/Object;)%s", toDesc(Type.getInternalName(MethodInvocationResult.class)));

    static final String ABSTRACT_METHOD_INVOCATION_INTERNAL_NAME = PlasticInternalUtils
            .toInternalName(AbstractMethodInvocation.class.getName());

    private static final String HANDLE_SHIM_BASE_CLASS_INTERNAL_NAME = Type
            .getInternalName(PlasticClassHandleShim.class);

    static final String STATIC_CONTEXT_INTERNAL_NAME = Type.getInternalName(StaticContext.class);

    private static final String INSTANCE_CONTEXT_INTERNAL_NAME = Type.getInternalName(InstanceContext.class);

    private static final String INSTANCE_CONTEXT_DESC = toDesc(INSTANCE_CONTEXT_INTERNAL_NAME);

    private static final String CONSTRUCTOR_DESC = String.format("(L%s;L%s;)V", STATIC_CONTEXT_INTERNAL_NAME,
            INSTANCE_CONTEXT_INTERNAL_NAME);

    static final Method STATIC_CONTEXT_GET_METHOD = toMethod(StaticContext.class, "get", int.class);

    static final Method COMPUTED_VALUE_GET_METHOD = toMethod(ComputedValue.class, "get", InstanceContext.class);

    private static final Method CONSTRUCTOR_CALLBACK_METHOD = toMethod(ConstructorCallback.class, "onConstruct",
            Object.class, InstanceContext.class);

    private static String toDesc(String internalName)
    {
        return "L" + internalName + ";";
    }

    private static Method toMethod(Class declaringClass, String methodName, Class... parameterTypes)
    {
        return PlasticUtils.getMethod(declaringClass, methodName, parameterTypes);
    }

    static <T> T safeArrayDeref(T[] array, int index)
    {
        if (array == null)
            return null;

        return array[index];
    }

    // Now past the inner classes; these are the instance variables of PlasticClassImpl proper:

    final ClassNode classNode;

    final PlasticClassPool pool;

    private final boolean proxy;

    final String className;

    private final String superClassName;

    private final AnnotationAccess annotationAccess;

    // All the non-introduced (and non-constructor) methods, in sorted order

    private final List<PlasticMethodImpl> methods;

    private final Map<MethodDescription, PlasticMethod> description2method = new HashMap<>();

    final Set<String> methodNames = new HashSet<>();

    private final List<ConstructorCallback> constructorCallbacks = PlasticInternalUtils.newList();

    // All non-introduced instance fields

    private final List<PlasticFieldImpl> fields;

    /**
     * Methods that require special attention inside {@link #createInstantiator()} because they
     * have method advice.
     */
    final Set<PlasticMethodImpl> advisedMethods = PlasticInternalUtils.newSet();

    final NameCache nameCache = new NameCache();

    // This is generated from fields, as necessary
    List<PlasticField> unclaimedFields;

    private final Set<String> fieldNames = PlasticInternalUtils.newSet();

    final StaticContext staticContext;

    final InheritanceData parentInheritanceData, inheritanceData;

    // MethodNodes in which field transformations should occur; this is most existing and
    // introduced methods, outside of special access methods.

    final Set<MethodNode> fieldTransformMethods = PlasticInternalUtils.newSet();

    // Tracks any methods that the Shim class uses to gain access to fields; used to ensure that
    // such methods are not optimized away incorrectly.
    final Set<MethodNode> shimInvokedMethods = PlasticInternalUtils.newSet();

    /**
     * Tracks instrumentations of fields of this class, including private fields which are not published into the
     * {@link PlasticClassPool}.
     */
    private final FieldInstrumentations fieldInstrumentations;

    /**
     * This normal no-arguments constructor, or null. By the end of the transformation
     * this will be converted into an ordinary method.
     */
    private MethodNode originalConstructor;

    private final MethodNode newConstructor;

    final InstructionBuilder constructorBuilder;

    private String instanceContextFieldName;

    private Class<?> transformedClass;

    // Indexes used to identify fields or methods in the shim
    int nextFieldIndex = 0;

    int nextMethodIndex = 0;

    // Set of fields that need to contribute to the shim and gain access to it

    final Set<PlasticFieldImpl> shimFields = PlasticInternalUtils.newSet();

    // Set of methods that need to contribute to the shim and gain access to it

    final Set<PlasticMethodImpl> shimMethods = PlasticInternalUtils.newSet();

    final ClassNode implementationClassNode;

    private ClassNode interfaceClassNode;

    /**
     * @param classNode
     * @param implementationClassNode
     * @param pool
     * @param parentInheritanceData
     * @param parentStaticContext
     * @param proxy
     */
    public PlasticClassImpl(ClassNode classNode, ClassNode implementationClassNode, PlasticClassPool pool, InheritanceData parentInheritanceData,
                            StaticContext parentStaticContext, boolean proxy)
    {
        this.classNode = classNode;
        this.pool = pool;
        this.proxy = proxy;
        this.implementationClassNode = implementationClassNode;

        staticContext = parentStaticContext.dupe();

        className = PlasticInternalUtils.toClassName(classNode.name);
        superClassName = PlasticInternalUtils.toClassName(classNode.superName);
        int lastIndexOfDot = className.lastIndexOf('.');

        String packageName = lastIndexOfDot > -1 ? className.substring(0, lastIndexOfDot) : "";

        fieldInstrumentations = new FieldInstrumentations(classNode.superName);

        annotationAccess = new DelegatingAnnotationAccess(pool.createAnnotationAccess(classNode.visibleAnnotations),
                pool.createAnnotationAccess(superClassName));

        this.parentInheritanceData = parentInheritanceData;

        inheritanceData = parentInheritanceData.createChild(packageName);

        for (String interfaceName : classNode.interfaces)
        {
            inheritanceData.addInterface(interfaceName);
        }

        methods = new ArrayList<>(classNode.methods.size());

        String invalidConstructorMessage = invalidConstructorMessage();

        for (MethodNode node : classNode.methods)
        {
            if (node.name.equals(CONSTRUCTOR_NAME))
            {
                if (node.desc.equals(NOTHING_TO_VOID))
                {
                    originalConstructor = node;
                    fieldTransformMethods.add(node);
                } else
                {
                    node.instructions.clear();

                    newBuilder(node).throwException(IllegalStateException.class, invalidConstructorMessage);
                }

                continue;
            }

            /*
             * Static methods are not visible to the main API methods, but they must still be transformed,
             * in case they directly access fields. In addition, track their names to avoid collisions.
             */
            if (Modifier.isStatic(node.access))
            {
                if (isInheritableMethod(node))
                {
                    inheritanceData.addMethod(node.name, node.desc, node.access == 0);
                }

                methodNames.add(node.name);

                fieldTransformMethods.add(node);

                continue;
            }

            if (!Modifier.isAbstract(node.access))
            {
                fieldTransformMethods.add(node);
            }

            PlasticMethodImpl pmi = new PlasticMethodImpl(this, node);

            methods.add(pmi);
            description2method.put(pmi.getDescription(), pmi);

            if (isInheritableMethod(node))
            {
                inheritanceData.addMethod(node.name, node.desc, node.access == 0);
            }

            methodNames.add(node.name);
        }

        methodNames.addAll(parentInheritanceData.methodNames());

        Collections.sort(methods);

        fields = new ArrayList<>(classNode.fields.size());

        for (FieldNode node : classNode.fields)
        {
            fieldNames.add(node.name);

            // Ignore static fields.

            if (Modifier.isStatic(node.access))
                continue;

            // When we instrument the field such that it must be private, we'll get an exception.

            fields.add(new PlasticFieldImpl(this, node));
        }

        Collections.sort(fields);

        // TODO: Make the output class's constructor protected, and create a shim class to instantiate it
        // efficiently (without reflection).
        newConstructor = new MethodNode(ACC_PUBLIC, CONSTRUCTOR_NAME, CONSTRUCTOR_DESC, null, null);
        constructorBuilder = newBuilder(newConstructor);

        // Start by calling the super-class no args constructor

        if (parentInheritanceData.isTransformed())
        {
            // If the parent is transformed, our first step is always to invoke its constructor.

            constructorBuilder.loadThis().loadArgument(0).loadArgument(1);
            constructorBuilder.invokeConstructor(superClassName, StaticContext.class.getName(),
                    InstanceContext.class.getName());
        } else
        {
            // Assumes the base class includes a visible constructor that takes no arguments.
            // TODO: Do a proper check for this case and throw a meaningful exception
            // if not present.

            constructorBuilder.loadThis().invokeConstructor(superClassName);
        }

        // During the transformation, we'll be adding code to the constructor to pull values
        // out of the static or instance context and assign them to fields.

        // Later on, we'll add the RETURN opcode
    }

    private String invalidConstructorMessage()
    {
        return String.format("Class %s has been transformed and may not be directly instantiated.", className);
    }

    @Override
    public <T extends Annotation> boolean hasAnnotation(Class<T> annotationType)
    {
        check();

        return annotationAccess.hasAnnotation(annotationType);
    }

    @Override
    public <T extends Annotation> T getAnnotation(Class<T> annotationType)
    {
        check();

        return annotationAccess.getAnnotation(annotationType);
    }

    private static void addMethodAndParameterAnnotationsFromExistingClass(MethodNode methodNode, MethodNode implementationMethodNode)
    {
        // visits the method attributes
        int i, j, n;
        if (implementationMethodNode.annotationDefault != null)
        {
            AnnotationVisitor av = methodNode.visitAnnotationDefault();
            AnnotationNode.accept(av, null, implementationMethodNode.annotationDefault);
            if (av != null)
            {
                av.visitEnd();
            }
        }
        n = implementationMethodNode.visibleAnnotations == null ? 0 : implementationMethodNode.visibleAnnotations.size();
        for (i = 0; i < n; ++i)
        {
            AnnotationNode an = implementationMethodNode.visibleAnnotations.get(i);
            an.accept(methodNode.visitAnnotation(an.desc, true));
        }
        n = implementationMethodNode.invisibleAnnotations == null ? 0 : implementationMethodNode.invisibleAnnotations.size();
        for (i = 0; i < n; ++i)
        {
            AnnotationNode an = implementationMethodNode.invisibleAnnotations.get(i);
            an.accept(methodNode.visitAnnotation(an.desc, false));
        }
        n = implementationMethodNode.visibleParameterAnnotations == null
                ? 0
                : implementationMethodNode.visibleParameterAnnotations.length;
        for (i = 0; i < n; ++i)
        {
            List<?> l = implementationMethodNode.visibleParameterAnnotations[i];
            if (l == null)
            {
                continue;
            }
            for (j = 0; j < l.size(); ++j)
            {
                AnnotationNode an = (AnnotationNode) l.get(j);
                an.accept(methodNode.visitParameterAnnotation(i, an.desc, true));
            }
        }
        n = implementationMethodNode.invisibleParameterAnnotations == null
                ? 0
                : implementationMethodNode.invisibleParameterAnnotations.length;
        for (i = 0; i < n; ++i)
        {
            List<?> l = implementationMethodNode.invisibleParameterAnnotations[i];
            if (l == null)
            {
                continue;
            }
            for (j = 0; j < l.size(); ++j)
            {
                AnnotationNode an = (AnnotationNode) l.get(j);
                an.accept(methodNode.visitParameterAnnotation(i, an.desc, false));
            }
        }

        methodNode.visitEnd();

    }

    private static void removeDuplicatedAnnotations(MethodNode node)
    {

        removeDuplicatedAnnotations(node.visibleAnnotations);
        removeDuplicatedAnnotations(node.invisibleAnnotations);

        if (node.visibleParameterAnnotations != null)
        {
            for (List<AnnotationNode> list : node.visibleParameterAnnotations)
            {
                removeDuplicatedAnnotations(list);
            }
        }

        if (node.invisibleParameterAnnotations != null)
        {
            for (List<AnnotationNode> list : node.invisibleParameterAnnotations)
            {
                removeDuplicatedAnnotations(list);
            }
        }

    }

    private static void removeDuplicatedAnnotations(ClassNode node)
    {
        removeDuplicatedAnnotations(node.visibleAnnotations, true);
        removeDuplicatedAnnotations(node.invisibleAnnotations, true);
    }

    private static void removeDuplicatedAnnotations(List<AnnotationNode> list) {
        removeDuplicatedAnnotations(list, false);
    }

    private static void removeDuplicatedAnnotations(List<AnnotationNode> list, boolean reverse) {

        if (list != null)
        {

            final Set<String> annotations = new HashSet<>();
            final List<AnnotationNode> toBeRemoved = new ArrayList<>();
            final List<AnnotationNode> toBeIterated;

            if (reverse)
            {
                toBeIterated = new ArrayList<>(list);
                Collections.reverse(toBeIterated);
            }
            else {
                toBeIterated = list;
            }

            for (AnnotationNode annotationNode : toBeIterated)
            {
                if (annotations.contains(annotationNode.desc))
                {
                    toBeRemoved.add(annotationNode);
                }
                else
                {
                    annotations.add(annotationNode.desc);
                }
            }

            for (AnnotationNode annotationNode : toBeRemoved)
            {
                list.remove(annotationNode);
            }

        }

    }

    private static String getParametersDesc(MethodNode methodNode) {
        return methodNode.desc.substring(methodNode.desc.indexOf('(') + 1, methodNode.desc.lastIndexOf(')'));
    }

    private static MethodNode findExactMatchMethod(MethodNode methodNode, ClassNode source) {

        MethodNode found = null;

        final String methodDescription = getParametersDesc(methodNode);

        for (MethodNode implementationMethodNode : source.methods)
        {

            final String implementationMethodDescription = getParametersDesc(implementationMethodNode);
            if (methodNode.name.equals(implementationMethodNode.name) &&
                    // We don't want synthetic methods.
                    ((implementationMethodNode.access & Opcodes.ACC_SYNTHETIC) == 0)
                    && (methodDescription.equals(implementationMethodDescription)))
            {
                found = implementationMethodNode;
                break;
            }
        }

        return found;

    }

    private static List<Class> getJavaParameterTypes(MethodNode methodNode) {
        final ClassLoader classLoader = PlasticInternalUtils.class.getClassLoader();
        Type[] parameterTypes = Type.getArgumentTypes(methodNode.desc);
        List<Class> list = new ArrayList<>();
        for (Type type : parameterTypes)
        {
            try
            {
                list.add(PlasticInternalUtils.toClass(classLoader, type.getClassName()));
            }
            catch (ClassNotFoundException e)
            {
                throw new RuntimeException(e); // shouldn't happen anyway
            }
        }
        return list;
    }

    /**
     * Returns the first method which matches the given methodNode.
     * FIXME: this may not find the correct method if the correct one is declared after
     * another in which all parameters are supertypes of the parameters of methodNode.
     * To solve this, we would need to dig way deeper than we have time for this.
     * @param methodNode
     * @param classNode
     * @return
     */
    private static MethodNode findGenericMethod(MethodNode methodNode, ClassNode classNode)
    {

        MethodNode found = null;

        List<Class> parameterTypes = getJavaParameterTypes(methodNode);

        for (MethodNode implementationMethodNode : classNode.methods)
        {

            if (methodNode.name.equals(implementationMethodNode.name))
            {

                final List<Class> implementationParameterTypes = getJavaParameterTypes(implementationMethodNode);

                if (parameterTypes.size() == implementationParameterTypes.size())
                {

                    boolean matches = true;
                    for (int i = 0; i < parameterTypes.size(); i++)
                    {
                        final Class implementationParameterType = implementationParameterTypes.get(i);
                        final Class parameterType = parameterTypes.get(i);
                        if (!parameterType.isAssignableFrom(implementationParameterType)) {
                            matches = false;
                            break;
                        }

                    }

                    if (matches && !isBridge(implementationMethodNode))
                    {
                        found = implementationMethodNode;
                        break;
                    }

                }

            }

        }

        return found;

    }

    private static void addMethodAndParameterAnnotationsFromExistingClass(MethodNode methodNode, ClassNode source)
    {
        if (source != null)
        {

            MethodNode candidate = findExactMatchMethod(methodNode, source);

            final String parametersDesc = getParametersDesc(methodNode);

            // candidate will be null when the method has generic parameters
            if (candidate == null && parametersDesc.trim().length() > 0)
            {
                candidate = findGenericMethod(methodNode, source);
            }

            if (candidate != null)
            {
                addMethodAndParameterAnnotationsFromExistingClass(methodNode, candidate);
            }

        }

    }

    /**
     * Tells whether a given method is a bridge one or not.
     * Notice the flag for bridge method is the same as volatile field. Java 6 doesn't have
     * Modifiers.isBridge(), so we use a workaround.
     */
    private static boolean isBridge(MethodNode methodNode)
    {
        return Modifier.isVolatile(methodNode.access);
    }

    @Override
    public PlasticClass proxyInterface(Class interfaceType, PlasticField field)
    {
        check();

        assert field != null;

        introduceInterface(interfaceType);

        for (Method m : getUniqueMethods(interfaceType))
        {
            final MethodDescription description = new MethodDescription(m);
            if(Modifier.isStatic(description.modifiers))
            {
                continue;
            }
            introduceMethod(description).delegateTo(field);
        }

        return this;
    }

    @Override
    public ClassInstantiator createInstantiator()
    {
        lock();

        addClassAnnotations(implementationClassNode);
        removeDuplicatedAnnotations(classNode);

        createShimIfNeeded();

        interceptFieldAccess();

        rewriteAdvisedMethods();

        completeConstructor();

        transformedClass = pool.realizeTransformedClass(classNode, inheritanceData, staticContext);

        return createInstantiatorFromClass(transformedClass);
    }

    private void addClassAnnotations(ClassNode otherClassNode)
    {
        // Copy annotations from implementation if available.
        // Code adapted from ClassNode.accept(), as we just want to copy
        // the annotations and nothing more.
        if (otherClassNode != null)
        {

            int i, n;
            n = otherClassNode.visibleAnnotations == null ? 0 : otherClassNode.visibleAnnotations.size();
            for (i = 0; i < n; ++i)
            {
                AnnotationNode an = otherClassNode.visibleAnnotations.get(i);
                an.accept(classNode.visitAnnotation(an.desc, true));
            }
            n = otherClassNode.invisibleAnnotations == null ? 0 : otherClassNode.invisibleAnnotations.size();
            for (i = 0; i < n; ++i)
            {
                AnnotationNode an = otherClassNode.invisibleAnnotations.get(i);
                an.accept(classNode.visitAnnotation(an.desc, false));
            }

        }
    }

    private ClassInstantiator createInstantiatorFromClass(Class clazz)
    {
        try
        {
            Constructor ctor = clazz.getConstructor(StaticContext.class, InstanceContext.class);

            return new ClassInstantiatorImpl(clazz, ctor, staticContext);
        } catch (Exception ex)
        {
            throw new RuntimeException(String.format("Unable to create ClassInstantiator for class %s: %s",
                    clazz.getName(), PlasticInternalUtils.toMessage(ex)), ex);
        }
    }

    private void completeConstructor()
    {
        if (originalConstructor != null)
        {
            convertOriginalConstructorToMethod();
        }

        invokeCallbacks();

        constructorBuilder.returnResult();

        classNode.methods.add(newConstructor);
    }

    private void invokeCallbacks()
    {
        for (ConstructorCallback callback : constructorCallbacks)
        {
            invokeCallback(callback);
        }
    }

    private void invokeCallback(ConstructorCallback callback)
    {
        int index = staticContext.store(callback);

        // First, load the callback

        constructorBuilder.loadArgument(0).loadConstant(index).invoke(STATIC_CONTEXT_GET_METHOD).castOrUnbox(ConstructorCallback.class.getName());

        // Load this and the InstanceContext
        constructorBuilder.loadThis().loadArgument(1);

        constructorBuilder.invoke(CONSTRUCTOR_CALLBACK_METHOD);
    }

    /**
     * Convert the original constructor into a private method invoked from the
     * generated constructor.
     */
    private void convertOriginalConstructorToMethod()
    {
        String initializerName = makeUnique(methodNames, "initializeInstance");

        int originalAccess = originalConstructor.access;

        originalConstructor.access = ACC_PRIVATE;
        originalConstructor.name = initializerName;

        stripOutSuperConstructorCall(originalConstructor);

        constructorBuilder.loadThis().invokeVirtual(className, "void", initializerName);

        // And replace it with a constructor that throws an exception

        MethodNode replacementConstructor = new MethodNode(originalAccess, CONSTRUCTOR_NAME, NOTHING_TO_VOID, null,
                null);

        newBuilder(replacementConstructor).throwException(IllegalStateException.class, invalidConstructorMessage());

        classNode.methods.add(replacementConstructor);
    }

    private void stripOutSuperConstructorCall(MethodNode cons)
    {
        InsnList ins = cons.instructions;

        ListIterator li = ins.iterator();

        // Look for the ALOAD 0 (i.e., push this on the stack)
        while (li.hasNext())
        {
            AbstractInsnNode node = (AbstractInsnNode) li.next();

            if (node.getOpcode() == ALOAD)
            {
                VarInsnNode varNode = (VarInsnNode) node;

                assert varNode.var == 0;

                // Remove the ALOAD
                li.remove();
                break;
            }
        }

        // Look for the call to the super-class, an INVOKESPECIAL
        while (li.hasNext())
        {
            AbstractInsnNode node = (AbstractInsnNode) li.next();

            if (node.getOpcode() == INVOKESPECIAL)
            {
                MethodInsnNode mnode = (MethodInsnNode) node;

                assert mnode.owner.equals(classNode.superName);
                assert mnode.name.equals(CONSTRUCTOR_NAME);
                assert mnode.desc.equals(cons.desc);

                li.remove();
                return;
            }
        }

        throw new AssertionError("Could not convert constructor to simple method.");
    }

    @Override
    public <T extends Annotation> List<PlasticField> getFieldsWithAnnotation(Class<T> annotationType)
    {
        check();

        List<PlasticField> result = getAllFields();

        Iterator<PlasticField> iterator = result.iterator();

        while (iterator.hasNext())
        {
            PlasticField plasticField = iterator.next();

            if (!plasticField.hasAnnotation(annotationType))
                iterator.remove();
        }

        return result;
    }

    @Override
    public List<PlasticField> getAllFields()
    {
        check();

        return new ArrayList<>(fields);
    }

    @Override
    public List<PlasticField> getUnclaimedFields()
    {
        check();

        // Initially null, and set back to null by PlasticField.claim().

        if (unclaimedFields == null)
        {
            unclaimedFields = new ArrayList<>(fields.size());

            for (PlasticField f : fields)
            {
                if (!f.isClaimed())
                    unclaimedFields.add(f);
            }
        }

        return unclaimedFields;
    }

    @Override
    public PlasticMethod introducePrivateMethod(String typeName, String suggestedName, String[] argumentTypes,
                                                String[] exceptionTypes)
    {
        check();

        assert PlasticInternalUtils.isNonBlank(typeName);
        assert PlasticInternalUtils.isNonBlank(suggestedName);

        String name = makeUnique(methodNames, suggestedName);

        MethodDescription description = new MethodDescription(Modifier.PRIVATE, typeName, name, argumentTypes, null,
                exceptionTypes);

        return introduceMethod(description);
    }

    @Override
    public PlasticField introduceField(String className, String suggestedName)
    {
        check();

        assert PlasticInternalUtils.isNonBlank(className);
        assert PlasticInternalUtils.isNonBlank(suggestedName);

        String name = makeUnique(fieldNames, suggestedName);

        // No signature and no initial value

        FieldNode fieldNode = new FieldNode(ACC_PRIVATE, name, PlasticInternalUtils.toDescriptor(className), null, null);

        classNode.fields.add(fieldNode);

        fieldNames.add(name);

        PlasticFieldImpl newField = new PlasticFieldImpl(this, fieldNode);

        return newField;
    }

    @Override
    public PlasticField introduceField(Class fieldType, String suggestedName)
    {
        assert fieldType != null;

        return introduceField(nameCache.toTypeName(fieldType), suggestedName);
    }

    String makeUnique(Set<String> values, String input)
    {
        return values.contains(input) ? input + "$" + PlasticUtils.nextUID() : input;
    }

    @Override
    public <T extends Annotation> List<PlasticMethod> getMethodsWithAnnotation(Class<T> annotationType)
    {
        check();

        List<PlasticMethod> result = getMethods();

        result.removeIf(method -> !method.hasAnnotation(annotationType));

        return result;
    }

    @Override
    public List<PlasticMethod> getMethods()
    {
        check();

        return new ArrayList<>(methods);
    }

    @Override
    public PlasticMethod introduceMethod(MethodDescription description)
    {
        check();

        if (Modifier.isAbstract(description.modifiers))
        {
            description = description.withModifiers(description.modifiers & ~ACC_ABSTRACT);
        }

        PlasticMethod result = description2method.get(description);

        if (result == null)
        {
            result = createNewMethod(description);

            description2method.put(description, result);
        }

        methodNames.add(description.methodName);

        // Note that is it not necessary to add the new MethodNode to
        // fieldTransformMethods (the default implementations provided by introduceMethod() do not
        // ever access instance fields) ... unless the caller invokes changeImplementation().

        return result;
    }

    @Override
    public PlasticMethod introduceMethod(MethodDescription description, InstructionBuilderCallback callback)
    {
        check();

        // TODO: optimize this so that a default implementation is not created.

        return introduceMethod(description).changeImplementation(callback);
    }

    @Override
    public PlasticMethod introduceMethod(Method method)
    {
        check();
        return introduceMethod(new MethodDescription(method));
    }

    void addMethod(MethodNode methodNode)
    {
        classNode.methods.add(methodNode);

        methodNames.add(methodNode.name);

        if (isInheritableMethod(methodNode))
        {
            inheritanceData.addMethod(methodNode.name, methodNode.desc, methodNode.access == 0);
        }
    }

    private PlasticMethod createNewMethod(MethodDescription description)
    {
        if (Modifier.isStatic(description.modifiers))
            throw new IllegalArgumentException(String.format(
                    "Unable to introduce method '%s' into class %s: introduced methods may not be static.",
                    description, className));

        String desc = nameCache.toDesc(description);

        String[] exceptions = new String[description.checkedExceptionTypes.length];
        for (int i = 0; i < exceptions.length; i++)
        {
            exceptions[i] = PlasticInternalUtils.toInternalName(description.checkedExceptionTypes[i]);
        }

        MethodNode methodNode = new MethodNode(description.modifiers, description.methodName, desc,
                description.genericSignature, exceptions);
        boolean isOverride = inheritanceData.isImplemented(methodNode.name, desc);

        if (!isOverride)
        {
            addMethodAndParameterAnnotationsFromExistingClass(methodNode, implementationClassNode);
            addMethodAndParameterAnnotationsFromExistingClass(methodNode, interfaceClassNode);
            removeDuplicatedAnnotations(methodNode);
        }

        if (isOverride)
            createOverrideOfBaseClassImpl(description, methodNode);
        else
            createNewMethodImpl(description, methodNode);

        addMethod(methodNode);

        return new PlasticMethodImpl(this, methodNode);
    }

    private void createNewMethodImpl(MethodDescription methodDescription, MethodNode methodNode)
    {
        newBuilder(methodDescription, methodNode).returnDefaultValue();
    }

    private void createOverrideOfBaseClassImpl(MethodDescription methodDescription, MethodNode methodNode)
    {
        InstructionBuilder builder = newBuilder(methodDescription, methodNode);

        builder.loadThis();
        builder.loadArguments();
        builder.invokeSpecial(superClassName, methodDescription);
        builder.returnResult();
    }

    /**
     * Iterates over all non-introduced methods, including the original constructor. For each
     * method, the bytecode is scanned for field reads and writes. When a match is found against an intercepted field,
     * the operation is replaced with a method invocation. This is invoked only after the {@link PlasticClassHandleShim}
     * for the class has been created, as the shim may create methods that contain references to fields that may be
     * subject to field access interception.
     */
    private void interceptFieldAccess()
    {
        for (MethodNode node : fieldTransformMethods)
        {
            // Intercept field access inside the method, tracking which access methods
            // are actually used by removing them from accessMethods

            interceptFieldAccess(node);
        }
    }

    /**
     * Determines if any fields or methods have provided FieldHandles or MethodHandles; if so
     * a shim class must be created to facilitate read/write access to fields, or invocation of methods.
     */
    private void createShimIfNeeded()
    {
        if (shimFields.isEmpty() && shimMethods.isEmpty())
            return;

        PlasticClassHandleShim shim = createShimInstance();

        installShim(shim);
    }

    public void installShim(PlasticClassHandleShim shim)
    {
        for (PlasticFieldImpl f : shimFields)
        {
            f.installShim(shim);
        }

        for (PlasticMethodImpl m : shimMethods)
        {
            m.installShim(shim);
        }
    }

    public PlasticClassHandleShim createShimInstance()
    {
        String shimClassName = String.format("%s$Shim_%s", classNode.name, PlasticUtils.nextUID());

        ClassNode shimClassNode = new ClassNode();

        shimClassNode.visit(PlasticConstants.DEFAULT_VERSION_OPCODE, ACC_PUBLIC | ACC_FINAL, shimClassName, null, HANDLE_SHIM_BASE_CLASS_INTERNAL_NAME,
                null);

        implementConstructor(shimClassNode);

        if (!shimFields.isEmpty())
        {
            implementShimGet(shimClassNode);
            implementShimSet(shimClassNode);
        }

        if (!shimMethods.isEmpty())
        {
            implementShimInvoke(shimClassNode);
        }

        return instantiateShim(shimClassNode);
    }

    private void implementConstructor(ClassNode shimClassNode)
    {
        MethodNode mn = new MethodNode(ACC_PUBLIC, CONSTRUCTOR_NAME, NOTHING_TO_VOID, null, null);

        InstructionBuilder builder = newBuilder(mn);

        builder.loadThis().invokeConstructor(PlasticClassHandleShim.class).returnResult();

        shimClassNode.methods.add(mn);

    }

    private PlasticClassHandleShim instantiateShim(ClassNode shimClassNode)
    {
        try
        {
            Class shimClass = pool.realize(className, ClassType.SUPPORT, shimClassNode);

            return (PlasticClassHandleShim) shimClass.newInstance();
        } catch (Exception ex)
        {
            throw new RuntimeException(
                    String.format("Unable to instantiate shim class %s for plastic class %s: %s",
                            PlasticInternalUtils.toClassName(shimClassNode.name), className,
                            PlasticInternalUtils.toMessage(ex)), ex);
        }
    }

    private void implementShimGet(ClassNode shimClassNode)
    {
        MethodNode mn = new MethodNode(ACC_PUBLIC, "get", OBJECT_INT_TO_OBJECT, null, null);

        InstructionBuilder builder = newBuilder(mn);

        // Arg 0 is the target instance
        // Arg 1 is the index

        builder.loadArgument(0).checkcast(className);
        builder.loadArgument(1);

        builder.startSwitch(0, nextFieldIndex - 1, new SwitchCallback()
        {
            @Override
            public void doSwitch(SwitchBlock block)
            {
                for (PlasticFieldImpl f : shimFields)
                {
                    f.extendShimGet(block);
                }
            }
        });

        shimClassNode.methods.add(mn);
    }

    private void implementShimSet(ClassNode shimClassNode)
    {
        MethodNode mn = new MethodNode(ACC_PUBLIC, "set", OBJECT_INT_OBJECT_TO_VOID, null, null);

        InstructionBuilder builder = newBuilder(mn);

        // Arg 0 is the target instance
        // Arg 1 is the index
        // Arg 2 is the new value

        builder.loadArgument(0).checkcast(className);
        builder.loadArgument(2);

        builder.loadArgument(1);

        builder.startSwitch(0, nextFieldIndex - 1, new SwitchCallback()
        {
            @Override
            public void doSwitch(SwitchBlock block)
            {
                for (PlasticFieldImpl f : shimFields)
                {
                    f.extendShimSet(block);
                }
            }
        });

        builder.returnResult();

        shimClassNode.methods.add(mn);
    }

    private void implementShimInvoke(ClassNode shimClassNode)
    {
        MethodNode mn = new MethodNode(ACC_PUBLIC, "invoke", OBJECT_INT_OBJECT_ARRAY_TO_METHOD_INVOCATION_RESULT, null,
                null);

        InstructionBuilder builder = newBuilder(mn);

        // Arg 0 is the target instance
        // Arg 1 is the index
        // Arg 2 is the object array of parameters

        builder.loadArgument(0).checkcast(className);

        builder.loadArgument(1);

        builder.startSwitch(0, nextMethodIndex - 1, new SwitchCallback()
        {
            @Override
            public void doSwitch(SwitchBlock block)
            {
                for (PlasticMethodImpl m : shimMethods)
                {
                    m.extendShimInvoke(block);
                }
            }
        });

        shimClassNode.methods.add(mn);
    }

    private void rewriteAdvisedMethods()
    {
        for (PlasticMethodImpl method : advisedMethods)
        {
            method.rewriteMethodForAdvice();
        }
    }

    private void interceptFieldAccess(MethodNode methodNode)
    {
        InsnList insns = methodNode.instructions;

        ListIterator<AbstractInsnNode> it = insns.iterator();

        while (it.hasNext())
        {
            AbstractInsnNode node = it.next();

            int opcode = node.getOpcode();

            if (opcode != GETFIELD && opcode != PUTFIELD)
            {
                continue;
            }

            FieldInsnNode fnode = (FieldInsnNode) node;

            FieldInstrumentation instrumentation = findFieldNodeInstrumentation(fnode, opcode == GETFIELD);

            if (instrumentation == null)
            {
                continue;
            }

            // Replace the field access node with the appropriate method invocation.

            insns.insertBefore(fnode, new MethodInsnNode(INVOKEVIRTUAL, fnode.owner, instrumentation.methodName, instrumentation.methodDescription, false));

            it.remove();
        }
    }

    private FieldInstrumentation findFieldNodeInstrumentation(FieldInsnNode node, boolean forRead)
    {
        // First look in the local fieldInstrumentations, which contains private field instrumentations
        // (as well as non-private ones).

        String searchStart = node.owner;

        if (searchStart.equals(classNode.name))
        {
            FieldInstrumentation result = fieldInstrumentations.get(node.name, forRead);

            if (result != null)
            {
                return result;
            }

            // Slight optimization: start the search in the super-classes' fields, since we've already
            // checked this classes fields.

            searchStart = classNode.superName;
        }

        return pool.getFieldInstrumentation(searchStart, node.name, forRead);
    }

    String getInstanceContextFieldName()
    {
        if (instanceContextFieldName == null)
        {
            instanceContextFieldName = makeUnique(fieldNames, "instanceContext");

            // TODO: We could use a protected field and only initialize
            // it once, in the first base class where it is needed, though that raises the possibilities
            // of name conflicts (a subclass might introduce a field with a conflicting name).

            FieldNode node = new FieldNode(ACC_PRIVATE | ACC_FINAL, instanceContextFieldName, INSTANCE_CONTEXT_DESC,
                    null, null);

            classNode.fields.add(node);

            // Extend the constructor to store the context in a field.

            constructorBuilder.loadThis().loadArgument(1)
                    .putField(className, instanceContextFieldName, InstanceContext.class);
        }

        return instanceContextFieldName;
    }

    /**
     * Creates a new private final field and initializes its value (using the StaticContext).
     */
    String createAndInitializeFieldFromStaticContext(String suggestedFieldName, String fieldType,
                                                     Object injectedFieldValue)
    {
        String name = makeUnique(fieldNames, suggestedFieldName);

        FieldNode field = new FieldNode(ACC_PRIVATE | ACC_FINAL, name, nameCache.toDesc(fieldType), null, null);

        classNode.fields.add(field);

        initializeFieldFromStaticContext(name, fieldType, injectedFieldValue);

        return name;
    }

    /**
     * Initializes a field from the static context. The injected value is added to the static
     * context and the class constructor updated to assign the value from the context (which includes casting and
     * possibly unboxing).
     */
    void initializeFieldFromStaticContext(String fieldName, String fieldType, Object injectedFieldValue)
    {
        int index = staticContext.store(injectedFieldValue);

        // Although it feels nicer to do the loadThis() later and then swap(), that breaks
        // on primitive longs and doubles, so its just easier to do the loadThis() first
        // so its at the right place on the stack for the putField().

        constructorBuilder.loadThis();

        constructorBuilder.loadArgument(0).loadConstant(index);
        constructorBuilder.invoke(STATIC_CONTEXT_GET_METHOD);
        constructorBuilder.castOrUnbox(fieldType);

        constructorBuilder.putField(className, fieldName, fieldType);
    }

    void pushInstanceContextFieldOntoStack(InstructionBuilder builder)
    {
        builder.loadThis().getField(className, getInstanceContextFieldName(), InstanceContext.class);
    }

    @Override
    public PlasticClass getPlasticClass()
    {
        return this;
    }

    @Override
    public Class<?> getTransformedClass()
    {
        if (transformedClass == null)
            throw new IllegalStateException(String.format(
                    "Transformed class %s is not yet available because the transformation is not yet complete.",
                    className));

        return transformedClass;
    }

    private boolean isInheritableMethod(MethodNode node)
    {
        return !Modifier.isPrivate(node.access);
    }

    @Override
    public String getClassName()
    {
        return className;
    }

    InstructionBuilderImpl newBuilder(MethodNode mn)
    {
        return newBuilder(PlasticInternalUtils.toMethodDescription(mn), mn);
    }

    InstructionBuilderImpl newBuilder(MethodDescription description, MethodNode mn)
    {
        return new InstructionBuilderImpl(description, mn, nameCache);
    }

    public Set<PlasticMethod> introduceInterface(Class interfaceType)
    {
        return introduceInterface(interfaceType, null);
    }

    private Set<PlasticMethod> introduceInterface(Class interfaceType, PlasticMethod method)
    {
        check();

        assert interfaceType != null;

        if (!interfaceType.isInterface())
            throw new IllegalArgumentException(String.format(
                    "Class %s is not an interface; only interfaces may be introduced.", interfaceType.getName()));

        String interfaceName = nameCache.toInternalName(interfaceType);

        try
        {
            interfaceClassNode = PlasticClassPool.readClassNode(interfaceType.getName(), getClass().getClassLoader());
        } catch (IOException e)
        {
            throw new RuntimeException(e);
        }

        if (!inheritanceData.isInterfaceImplemented(interfaceName))
        {
            classNode.interfaces.add(interfaceName);
            inheritanceData.addInterface(interfaceName);
        }

        addClassAnnotations(interfaceClassNode);

        Set<PlasticMethod> introducedMethods = new HashSet<PlasticMethod>();
        Set<Method> alreadyIntroducedMethods = new HashSet<>();

        Method[] sortedMethods = interfaceType.getMethods();
        Arrays.sort(sortedMethods, METHOD_COMPARATOR);
        for (Method m : sortedMethods)
        {
            MethodDescription description = new MethodDescription(m);

            if (!isMethodImplemented(description) &&
                    !(m.isDefault() && m.isBridge()) &&
                    !Modifier.isStatic(description.modifiers) &&
                    !contains(alreadyIntroducedMethods, m))
            {
                PlasticMethod introducedMethod = introduceMethod(m);
                introducedMethods.add(introducedMethod);
                if (method != null) {
                    introducedMethod.delegateTo(method);
                }
                alreadyIntroducedMethods.add(m);
            }
        }

        interfaceClassNode = null;

        return introducedMethods;
    }

    @Override
    public PlasticClass proxyInterface(Class interfaceType, PlasticMethod method)
    {
        check();
        assert method != null;

        introduceInterface(interfaceType, method);

        return this;
    }

    private boolean contains(Set<Method> alreadyIntroducedMethods, Method m) {
        boolean contains = false;
        for (Method method : alreadyIntroducedMethods)
        {
            if (METHOD_COMPARATOR.compare(method, m) == 0)
            {
                contains = true;
                break;
            }
        }
        return false;
    }

    private Map<MethodSignature, MethodDescription> createMethodSignatureMap(Class interfaceType) {
        // TAP-2582: preprocessing the method list so we don't add duplicated
        // methods, something that happens when an interface has superinterfaces
        // and they define the same method signature.
        // In addition, we collect all the thrown checked exceptions, just in case.
        Map<MethodSignature, MethodDescription> map = new HashMap<>();
        for (Method m : interfaceType.getMethods())
        {
            final MethodSignature methodSignature = new MethodSignature(m);
            final MethodDescription newMethodDescription = new MethodDescription(m);
            if (!map.containsKey(methodSignature))
            {
                map.put(methodSignature, newMethodDescription);
            }
            else
            {
                if (newMethodDescription.checkedExceptionTypes != null && newMethodDescription.checkedExceptionTypes.length > 0)
                {
                    final MethodDescription methodDescription = map.get(methodSignature);
                        final Set<String> checkedExceptionTypes = new HashSet<>();
                        checkedExceptionTypes.addAll(Arrays.asList(methodDescription.checkedExceptionTypes));
                        checkedExceptionTypes.addAll(Arrays.asList(newMethodDescription.checkedExceptionTypes));
                        map.put(methodSignature, new MethodDescription(
                            methodDescription,
                            checkedExceptionTypes.toArray(new String[checkedExceptionTypes.size()])));
                }
            }
        }
        return map;
    }

    final private static class MethodSignature implements Comparable<MethodSignature> {
        final private Method method;
        final private String name;
        final private Class<?>[] parameterTypes;

        public MethodSignature(Method method) {
            this.method = method;
            this.name = method.getName();
            this.parameterTypes = method.getParameterTypes();
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + Arrays.hashCode(parameterTypes);
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (obj == null) return false;
            if (getClass() != obj.getClass()) return false;

            MethodSignature other = (MethodSignature) obj;
            if (!Arrays.equals(parameterTypes, other.parameterTypes)) return false;

            return name == null ? other.name == null : name.equals(other.name);
        }

        @Override
        public int compareTo(MethodSignature o) {
            return method.getName().compareTo(o.method.getName());
        }
    }

    @Override
    public PlasticClass addToString(final String toStringValue)
    {
        check();

        if (!isMethodImplemented(PlasticUtils.TO_STRING_DESCRIPTION))
        {
            introduceMethod(PlasticUtils.TO_STRING_DESCRIPTION, new InstructionBuilderCallback()
            {
                @Override
                public void doBuild(InstructionBuilder builder)
                {
                    builder.loadConstant(toStringValue).returnResult();
                }
            });
        }

        return this;
    }

    @Override
    public boolean isMethodImplemented(MethodDescription description)
    {
        return inheritanceData.isImplemented(description.methodName, nameCache.toDesc(description));
    }

    @Override
    public boolean isInterfaceImplemented(Class interfaceType)
    {
        assert interfaceType != null;
        assert interfaceType.isInterface();

        String interfaceName = nameCache.toInternalName(interfaceType);

        return inheritanceData.isInterfaceImplemented(interfaceName);
    }

    @Override
    public String getSuperClassName()
    {
        return superClassName;
    }

    @Override
    public PlasticClass onConstruct(ConstructorCallback callback)
    {
        check();

        assert callback != null;

        constructorCallbacks.add(callback);

        return this;
    }

    void redirectFieldWrite(String fieldName, boolean privateField, MethodNode method)
    {
        FieldInstrumentation fi = new FieldInstrumentation(method.name, method.desc);

        fieldInstrumentations.write.put(fieldName, fi);

        if (!proxy)
        {
            pool.setFieldWriteInstrumentation(classNode.name, fieldName, fi);
        }
    }

    void redirectFieldRead(String fieldName, boolean privateField, MethodNode method)
    {
        FieldInstrumentation fi = new FieldInstrumentation(method.name, method.desc);

        fieldInstrumentations.read.put(fieldName, fi);

        if (!proxy)
        {
            pool.setFieldReadInstrumentation(classNode.name, fieldName, fi);
        }
    }

    final private MethodComparator METHOD_COMPARATOR = new MethodComparator();

    final private class MethodComparator implements Comparator<Method>
    {

        @Override
        public int compare(Method o1, Method o2)
        {

            int comparison = comparison = o1.getName().compareTo(o2.getName());

            if (comparison == 0)
            {
                comparison = o1.getParameterTypes().length - o2.getParameterTypes().length;
            }

            if (comparison == 0)
            {
                final int count = o1.getParameterTypes().length;
                for (int i = 0; i < count; i++)
                {
                    Class p1 = o1.getParameterTypes()[i];
                    Class p2 = o1.getParameterTypes()[i];
                    if (!p1.equals(p2))
                    {
                        comparison = p1.getName().compareTo(p2.getName());
                        break;
                    }
                }
            }

            if (comparison == 0)
            {
                // Trying to get methods lower in the interface hierarchy sorted before the same methods
                // higher in the hierarchy
                Class<?> declaringClass1 = o1.getDeclaringClass();
                Class<?> declaringClass2 = o2.getDeclaringClass();
                if (declaringClass1.isInterface() && declaringClass2.isInterface() &&
                        !declaringClass1.equals(declaringClass2)) {
                    if (declaringClass1.isAssignableFrom(declaringClass2))
                    {
                        comparison = -1;
                    }
                    else if (declaringClass1.isAssignableFrom(declaringClass2))
                    {
                        comparison = 1;
                    }
                }
            }

            return comparison;
        }
    }

    private List<Method> getUniqueMethods(Class interfaceType)
    {
        final List<Method> unique = new ArrayList<>(Arrays.asList(interfaceType.getMethods()));
        Collections.sort(unique, METHOD_COMPARATOR);
        Method last = null;
        Iterator<Method> iterator = unique.iterator();
        while (iterator.hasNext())
        {
            Method m = iterator.next();
            if (last != null && METHOD_COMPARATOR.compare(m, last) == 0)
            {
                last = m;
                iterator.remove();
            }
        }
        return unique;
    }

    @Override
    public String toString()
    {
        return String.format("PlasticClassImpl[%s]", className);
    }
}


text:
@interface NSArray (SPJSONKitAdapterCategories)
- (NSData *)sp_JSONData;
- (NSString *)sp_JSONString;
- (NSString *)sp_JSONStringWithError:(NSError **)error;
@end

@interface NSDictionary (SPJSONKitAdapterCategories)
- (NSString *)sp_JSONString;
- (NSString *)sp_JSONStringWithError:(NSError **)error;
@end

@interface NSString (SPJSONKitAdapterCategories)
- (id)sp_objectFromJSONString;
- (id)sp_objectFromJSONStringWithError:(NSError**)error;
@end

@interface NSData (SPJSONKitAdapterCategories)
- (id)sp_objectFromJSONString;
- (id)sp_objectFromJSONStringWithError:(NSError **)error;
@end

redpajama_set_name: RedPajamaGithub


text:
namespace base {
class Version;
class WaitableEvent;
}  // namespace base

namespace gvr {
class GvrApi;
}

namespace vr {

class VrInputConnection;
class VrShell;
struct KeyboardTestInput;

class VrGLThread : public base::android::JavaHandlerThread,
                   public PlatformInputHandler,
                   public BrowserRendererBrowserInterface,
                   public GlBrowserInterface,
                   public UiBrowserInterface,
                   public BrowserUiInterface {
 public:
  VrGLThread(
      const base::WeakPtr<VrShell>& weak_vr_shell,
      scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
      gvr_context* gvr_api,
      const UiInitialState& ui_initial_state,
      bool reprojected_rendering,
      bool daydream_support,
      bool pause_content,
      bool low_density,
      base::WaitableEvent* gl_surface_created_event,
      base::OnceCallback<gfx::AcceleratedWidget()> surface_callback);

  VrGLThread(const VrGLThread&) = delete;
  VrGLThread& operator=(const VrGLThread&) = delete;

  ~VrGLThread() override;
  base::WeakPtr<BrowserRenderer> GetBrowserRenderer();
  void SetInputConnection(VrInputConnection* input_connection);

  // GlBrowserInterface implementation (GL calling to VrShell).
  void ContentSurfaceCreated(jobject surface,
                             gl::SurfaceTexture* texture) override;
  void ContentOverlaySurfaceCreated(jobject surface,
                                    gl::SurfaceTexture* texture) override;
  void GvrDelegateReady() override;
  void SendRequestPresentReply(device::mojom::XRSessionPtr) override;
  void DialogSurfaceCreated(jobject surface,
                            gl::SurfaceTexture* texture) override;
  void ToggleCardboardGamepad(bool enabled) override;

  // BrowserRendererBrowserInterface implementation (BrowserRenderer calling to
  // VrShell).
  void ForceExitVr() override;
  void ReportUiOperationResultForTesting(
      const UiTestOperationType& action_type,
      const UiTestOperationResult& result) override;

  // PlatformInputHandler
  void ForwardEventToPlatformUi(std::unique_ptr<InputEvent> event) override;
  void ForwardEventToContent(std::unique_ptr<InputEvent> event,
                             int content_id) override;
  void ClearFocusedElement() override;
  void OnWebInputEdited(const TextEdits& edits) override;
  void SubmitWebInput() override;
  void RequestWebInputText(TextStateUpdateCallback callback) override;

  // UiBrowserInterface implementation (UI calling to VrShell).
  void ExitPresent() override;
  void ExitFullscreen() override;
  void Navigate(GURL gurl, NavigationMethod method) override;
  void NavigateBack() override;
  void NavigateForward() override;
  void ReloadTab() override;
  void OpenNewTab(bool incognito) override;
  void OpenBookmarks() override;
  void OpenRecentTabs() override;
  void OpenHistory() override;
  void OpenDownloads() override;
  void OpenShare() override;
  void OpenSettings() override;
  void CloseAllIncognitoTabs() override;
  void OpenFeedback() override;
  void CloseHostedDialog() override;
  void OnUnsupportedMode(UiUnsupportedMode mode) override;
  void OnExitVrPromptResult(ExitVrPromptChoice choice,
                            UiUnsupportedMode reason) override;
  void OnContentScreenBoundsChanged(const gfx::SizeF& bounds) override;
  void SetVoiceSearchActive(bool active) override;
  void StartAutocomplete(const AutocompleteRequest& request) override;
  void StopAutocomplete() override;
  void ShowPageInfo() override;

  // BrowserUiInterface implementation (Browser calling to UI).
  void SetWebVrMode(bool enabled) override;
  void SetFullscreen(bool enabled) override;
  void SetLocationBarState(const LocationBarState& state) override;
  void SetIncognito(bool incognito) override;
  void SetLoading(bool loading) override;
  void SetLoadProgress(float progress) override;
  void SetHistoryButtonsEnabled(bool can_go_back, bool can_go_forward) override;
  void SetCapturingState(
      const CapturingStateModel& active_capturing,
      const CapturingStateModel& background_capturing,
      const CapturingStateModel& potential_capturing) override;
  void ShowExitVrPrompt(UiUnsupportedMode reason) override;
  void SetSpeechRecognitionEnabled(bool enabled) override;
  void SetHasOrCanRequestRecordAudioPermission(
      bool has_or_can_request_record_audio) override;
  void SetRecognitionResult(const std::u16string& result) override;
  void OnSpeechRecognitionStateChanged(int new_state) override;
  void SetOmniboxSuggestions(std::vector<OmniboxSuggestion> result) override;
  void OnAssetsLoaded(AssetsLoadStatus status,
                      std::unique_ptr<Assets> assets,
                      const base::Version& component_version) override;
  void OnAssetsUnavailable() override;
  void WaitForAssets() override;
  void SetRegularTabsOpen(bool open) override;
  void SetIncognitoTabsOpen(bool open) override;
  void SetOverlayTextureEmpty(bool empty) override;
  void ShowSoftInput(bool show) override;
  void UpdateWebInputIndices(int selection_start,
                             int selection_end,
                             int composition_start,
                             int composition_end) override;
  void OnSwapContents(int new_content_id) override;
  void SetDialogLocation(float x, float y) override;
  void SetDialogFloating(bool floating) override;
  void ShowPlatformToast(const std::u16string& text) override;
  void CancelPlatformToast() override;
  void OnContentBoundsChanged(int width, int height) override;
  void PerformKeyboardInputForTesting(
      KeyboardTestInput keyboard_input) override;
  void SetVisibleExternalPromptNotification(
      ExternalPromptNotificationType prompt) override;

 protected:
  void Init() override;
  void CleanUp() override;

 private:
  bool OnMainThread() const;
  bool OnGlThread() const;

  base::WeakPtr<VrShell> weak_vr_shell_;
  base::WeakPtr<BrowserUiInterface> weak_browser_ui_;
  base::WeakPtr<VrInputConnection> weak_input_connection_;
  // Both VrInputConnection and VrGlThread are owned by VrShell. In VrShell, we
  // made sure that this input_connection_ is up to date and destroyed after
  // VrGlThread. So it is safe to use raw pointer here.
  raw_ptr<VrInputConnection> input_connection_ = nullptr;

  scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;

  // Created on GL thread.
  std::unique_ptr<UiFactory> ui_factory_;
  std::unique_ptr<BrowserRenderer> browser_renderer_;
  std::unique_ptr<gvr::GvrApi> gvr_api_;

  // This state is used for initializing the BrowserRenderer.
  std::unique_ptr<BrowserRendererFactory::Params> factory_params_;
};

}  // namespace vr

#endif  // CHROME_BROWSER_ANDROID_VR_VR_GL_THREAD_H_


text:
network='locked-down'
# network='totally-bogus'

echo 'Launching Cloudera Director instance'
info=$(gcloud compute instances create gg-director \
              --zone us-central1-c \
              --disk name=gg-director-2-4,boot=yes \
              --machine-type n1-standard-2 \
              --labels owner=gregoryg \
              --metadata owner=gregoryg \
              --network ${network} \
              --format="value(networkInterfaces[0].accessConfigs[0].natIP:label=EXTERNAL_IP,networkInterfaces[0].networkIP:label=INTERNAL_IP,status)")
if [ "$?" != 0 ] ; then
    exit 1
fi

dir_ip=`echo $info | cut -d' ' -f1`
echo Director external IP is $dir_ip
ssh-keygen -q -R ${dir_ip}

# echo "Launching the MIT KDC instance with assigned IP"
# info=$(gcloud compute instances create gg-new-kdc \
#               --zone us-central1-f \
#               --disk name=gg-new-kdc,boot=yes \
#               --address 35.184.170.133 \
#               --machine-type n1-standard-2 \
#               --labels owner=gregoryg \
#               --metadata owner=gregoryg \
#               --network gg-kdc \
#               --format="value(networkInterfaces[0].accessConfigs[0].natIP:label=EXTERNAL_IP,networkInterfaces[0].networkIP:label=INTERNAL_IP,status)")
# echo $info
# kdc_ip=`echo $info | cut -d' ' -f1`

# echo 'Launching MySQL metadata instance'
# info=$(gcloud compute instances create dir-mysql \
    #        --zone us-central1-c \
    #        --disk name=mysql-for-metadata,boot=yes \
    #        --disk name=mysql-metadata-disk1,boot=no \
    #        --machine-type n1-highmem-2 \
    #        --metadata owner=gregoryg \
    #        --network ${network} \
    #        --format="value(networkInterfaces[0].accessConfigs[0].natIP:label=EXTERNAL_IP,networkInterfaces[0].networkIP:label=INTERNAL_IP,status)")
# echo $info
# mysql_ip=`echo $info | cut -d' ' -f1`
# if [ "$?" != 0 ] ; then
#    exit 1
# fi

echo 'Fixing up the .ssh/config file'
sed -i.bak "/^ *Host director-server */,/^ *Host /{s/^\( *Hostname *\)\(.*\)/\1$dir_ip/}" ~/.ssh/config
diff ~/.ssh/config.bak ~/.ssh/config

# sed -i.bak "/^ *Host kdc-1 */,/^ *Host /{s/^\( *Hostname *\)\(.*\)/\1$kdc_ip/}" ~/.ssh/config
# diff ~/.ssh/config.bak ~/.ssh/config

# sed -i.bak "/^ *Host mysql */,/^ *Host /{s/^\( *Hostname *\)\(.*\)/\1$mysql_ip/}" ~/.ssh/config
# diff ~/.ssh/config.bak ~/.ssh/config

dirhost=`ssh gregj@director-server "hostname -f"`
ssh -tt gregj@director-server "sudo yum -y install nc netcat"

echo Starting proxy
emacsclient -n '/gregj@director-server:'
echo waiting for Director to become available
for i in 1 2 3 4 5 6 7 8 9 10
do
    ssh gregj@${dir_ip} 'nc `hostname -f` 7189 < /dev/null'
    ret=$?
    if [ ${ret} == 0 ] ; then
        echo Opening Director web page
        open "http://${dirhost}:7189/"
        break
    else
        echo -n .
        sleep 10
    fi
done
echo

echo Cloudera Director URL is http://${dirhost}:7189/
echo 'Done!'

## sample provisioning of an image without a saved boot disk
# gcloud compute instances create gg-centos7 \
    #        --zone us-central1-c \
    #        --machine-type n1-standard-2 \
    #        --boot-disk-size=200GB \
    #        --description "image play" \
    #        --image "https://www.googleapis.com/compute/v1/projects/centos-cloud/global/images/centos-7-v20170620" \
    #        --labels owner=gregoryg \
    #        --metadata owner=gregoryg \
    #        --network ${network}  \
    #        --format="value(networkInterfaces[0].accessConfigs[0].natIP:label=EXTERNAL_IP,networkInterfaces[0].networkIP:label=INTERNAL_IP,status)"


text:
require 'helper'
require 'fileutils'

describe RoxClient::Config do
  include Capture::Helpers
  include FakeFS::SpecHelpers
  Server ||= RoxClient::Server
  Project ||= RoxClient::Project

  let(:config){ RoxClient::Config.new }
  let(:project_double){ double update: nil }
  let(:server_doubles){ [] }
  subject{ config }

  before :each do
    Project.stub(:new).and_return(project_double)
    Server.stub(:new){ |options| server_double(options).tap{ |d| server_doubles << d } }
  end

  describe ".config" do
    let(:new_config){ double load: nil }
    before(:each){ RoxClient::Config.stub new: new_config }

    it "should create, load and memoize a configuration" do
      expect(new_config).to receive(:load).once
      3.times{ expect(RoxClient.config).to be(new_config) }
    end
  end

  describe ".configure" do
    let(:load_warnings){ [] }
    let(:config){ double load: nil, load_warnings: load_warnings }
    before(:each){ RoxClient.stub config: config }

    it "should yield and return the configuration" do
      result = nil
      expect{ |b| result = RoxClient.configure &b }.to yield_with_args(config)
      expect(result).to be(config)
    end

    describe "with load warnings" do
      let(:load_warnings){ [ 'a', 'b' ] }

      it "should print load warnings" do
        c = capture{ RoxClient.configure }
        expect(c.stdout).to be_empty
        expect(c.stderr).to match('ROX - a')
        expect(c.stderr).to match('ROX - b')
      end
    end
  end

  describe ".integrate" do
    let(:calls){ [] }
    let(:blocks){ Array.new(3){ |i| lambda{ |*args| calls << args } } }
    let(:config){ double load: nil, load_warnings: [] }
    before(:each){ RoxClient.stub config: config }

    it "should allow to register configuration blocks" do
      blocks.each{ |block| RoxClient.integrate &block }
      RoxClient.configure
      expect(calls).to eq([ [ config ], [ config ], [ config ] ])
    end
  end

  describe "when created" do
    subject{ RoxClient::Config }

    it "should create a project" do
      expect(Project).to receive(:new)
      subject.new
    end
  end

  before :each do
    @rox_env_vars = ENV.select{ |k,v| k.match /\AROX_/ }.each_key{ |k| ENV.delete k }
  end

  after :each do
    @rox_env_vars.each_pair{ |k,v| ENV[k] = v }
  end

  describe "default attributes" do
    its(:publish?){ should be_false }
    its(:local_mode?){ should be_false }
    its(:project){ should be(project_double) }
    its(:cache_payload?){ should be_false }
    its(:print_payload?){ should be_false }
    its(:save_payload?){ should be_false }
    its(:servers){ should be_empty }
    its(:server){ should be_nil }
    its(:workspace){ should be_nil }
  end

  it "should expand the workspace" do
    subject.workspace = 'foo'
    expect(subject.workspace).to eq(File.expand_path('foo'))
  end

  describe "when loaded" do
    let(:home_config){ nil }
    let(:home_config_path){ File.expand_path('~/.rox/config.yml') }
    let(:working_config){ nil }
    let(:working_config_path){ '/project/rox.yml' }
    let(:loaded_config){ config.tap &:load }

    before :each do
      FileUtils.mkdir_p '/project'
      FileUtils.mkdir_p File.dirname(home_config_path)
      FileUtils.mkdir_p File.dirname(working_config_path)
      File.open(home_config_path, 'w'){ |f| f.write home_config.strip } if home_config
      File.open(working_config_path, 'w'){ |f| f.write working_config.strip } if working_config
      Dir.chdir '/project'
    end

    describe "with full information in the home config" do
      let(:home_config){ %|
servers:
  a:
    apiUrl: "http://example.com/api"
    apiKeyId: "0123456789"
    apiKeySecret: "abcdefghijklmnopqrstuvwxyz"
    projectApiId: "9876543210"
  b:
    apiUrl: "http://subdomain.example.com/api"
    apiKeyId: "1234567890"
    apiKeySecret: "bcdefghijklmnopqrstuvwxyza"
project:
  name: A project
  version: 1.2.3
  apiId: "0123456789"
  category: A category
  tags: [ a, b ]
  tickets: [ c, d ]
publish: true
local: true
server: a
workspace: /old
payload:
  cache: false
  print: true
  save: false
      | }

      it "should have no load warnings" do
        expect(loaded_config.load_warnings).to be_empty
      end

      it "should create a project" do
        expect(project_double).to receive(:update).with({
          name: 'A project',
          version: '1.2.3',
          api_id: '9876543210',
          category: 'A category',
          tags: [ 'a', 'b' ],
          tickets: [ 'c', 'd' ]
        })
        config.load
        expect(config.project).to be(project_double)
      end

      it "should set the publishing attributes" do
        expect(attrs_hash(loaded_config, :publish?, :local_mode?)).to eq({
          publish?: true,
          local_mode?: true
        });
      end

      it "should set the workspace attributes" do
        expect(attrs_hash(loaded_config, :workspace, :cache_payload?, :print_payload?, :save_payload?)).to eq({
          workspace: '/old',
          cache_payload?: false,
          print_payload?: true,
          save_payload?: false
        })
      end

      it "should return client options" do
        expect(loaded_config.client_options).to eq({
          publish: true,
          local_mode: true,
          workspace: '/old',
          cache_payload: false,
          print_payload: true,
          save_payload: false
        })
      end

      it "should create two servers" do
        expect(Server).to receive(:new).with({
          name: 'a',
          api_url: 'http://example.com/api',
          api_key_id: '0123456789',
          api_key_secret: 'abcdefghijklmnopqrstuvwxyz',
          project_api_id: '9876543210'
        }).ordered
        expect(Server).to receive(:new).with({
          name: 'b',
          api_url: 'http://subdomain.example.com/api',
          api_key_id: '1234567890',
          api_key_secret: 'bcdefghijklmnopqrstuvwxyza',
          project_api_id: '0123456789'
        })
        config.load
        expect(config.servers).to eq(server_doubles)
      end

      it "should select the specified server" do
        expect(loaded_config.server).to eq(loaded_config.servers[0])
      end

      shared_examples_for "an overriden config" do

        it "should have no load warnings" do
          expect(loaded_config.load_warnings).to be_empty
        end

        it "should override project attributes" do
          expect(project_double).to receive(:update).with({
            name: 'Another project',
            version: '2.3.4',
            api_id: '9876543210',
            category: 'Another category',
            tags: 'oneTag',
            tickets: [ 'c', 'd' ]
          })
          config.load
          expect(config.project).to be(project_double)
        end

        it "should override the publishing attributes" do
          expect(attrs_hash(loaded_config, :publish?, :local_mode?)).to eq({
            publish?: true,
            local_mode?: false
          });
        end

        it "should set the workspace attributes" do
          expect(attrs_hash(loaded_config, :workspace, :cache_payload?, :print_payload?, :save_payload?)).to eq({
            workspace: '/tmp',
            cache_payload?: true,
            print_payload?: false,
            save_payload?: true
          })
        end

        it "should override client options" do
          expect(loaded_config.client_options).to eq({
            publish: true,
            local_mode: false,
            workspace: '/tmp',
            cache_payload: true,
            print_payload: false,
            save_payload: true
          })
        end

        it "should create two servers" do
          expect(Server).to receive(:new).with({
            name: 'a',
            api_url: 'http://example.com/api',
            api_key_id: '0123456789',
            api_key_secret: 'abcdefghijklmnopqrstuvwxyz',
            project_api_id: '9876543210'
          }).ordered
          expect(Server).to receive(:new).with({
            name: 'b',
            api_url: 'http://other-subdomain.example.com/api',
            api_key_id: '2345678901',
            api_key_secret: 'cdefghijklmnopqrstuvwxyzab',
            project_api_id: '0000000000'
          })
          config.load
          expect(config.servers).to eq(server_doubles)
        end

        it "should select the specified server" do
          expect(loaded_config.server).to eq(loaded_config.servers[0])
        end

        describe "with overriding environment variables" do
          let :rox_env_vars do
            {
              publish: '0',
              local: '1',
              server: 'b',
              workspace: '/opt',
              cache_payload: '0',
              print_payload: '1'
            }
          end
          before(:each){ rox_env_vars.each_pair{ |k,v| ENV["ROX_#{k.upcase}"] = v } }

          it "should have no load warnings" do
            expect(subject.load_warnings).to be_empty
          end

          it "should override the publishing attributes" do
            expect(attrs_hash(loaded_config, :publish?, :local_mode?)).to eq({
              publish?: false,
              local_mode?: true
            });
          end

          it "should set the workspace attributes" do
            expect(attrs_hash(loaded_config, :workspace, :cache_payload?, :print_payload?, :save_payload?)).to eq({
              workspace: '/opt',
              cache_payload?: false,
              print_payload?: true,
              save_payload?: true
            })
          end

          it "should select the specified server" do
            expect(loaded_config.server).to eq(loaded_config.servers[1])
          end
        end
      end

      describe "with an overriding working directory config" do
        let(:working_config){ %|
servers:
  b:
    apiUrl: "http://other-subdomain.example.com/api"
    apiKeyId: "2345678901"
    apiKeySecret: "cdefghijklmnopqrstuvwxyzab"
project:
  name: Another project
  version: 2.3.4
  apiId: "0000000000"
  category: Another category
  tags: oneTag
payload:
  cache: true
  print: false
  save: true
publish: true
local: false
workspace: /tmp
        | }

        it_should_behave_like "an overriden config"

        describe "with $ROX_CONFIG overriding the working file path" do
          let(:working_config_path){ '/tmp/foo/rox.yml' }
          before(:each){ ENV['ROX_CONFIG'] = '/tmp/foo/rox.yml' }
          it_should_behave_like "an overriden config"
        end
      end
    end

    describe "load warnings" do
      subject{ loaded_config }

      describe "with no config files" do
        its(:server){ should be_nil }
        its(:publish?){ should be_false }
        its(:load_warnings){ should have(1).items }
        it("should warn that no config file was found"){ should have_elements_matching(:load_warnings, /no config file found/, home_config_path, working_config_path) }
      end

      describe "with no server" do
        let(:working_config){ "publish: true" }
        its(:server){ should be_nil }
        its(:publish?){ should be_true }
        its(:load_warnings){ should have(1).items }
        it{ should have_elements_matching(:load_warnings, /no server defined/i) }
      end

      describe "with no server selected" do
        let(:working_config){ %|
servers:
  a:
    apiUrl: http://example.com/api
publish: true
        | }
        its(:server){ should be_nil }
        its(:publish?){ should be_true }
        its(:load_warnings){ should have(1).items }
        it{ should have_elements_matching(:load_warnings, /no server name given/i) }
      end

      describe "with an unknown server selected" do
        let(:working_config){ %|
servers:
  a:
    apiUrl: http://example.com/api
publish: true
server: unknown
        | }
        its(:server){ should be_nil }
        its(:publish?){ should be_true }
        its(:load_warnings){ should have(1).items }
        it{ should have_elements_matching(:load_warnings, /unknown server 'unknown'/i) }
      end
    end
  end

  def server_double options = {}
    double name: options[:name].to_s.strip, project_api_id: options[:project_api_id]
  end

  def attrs_hash source, *attrs
    attrs.inject({}){ |memo,a| memo[a.to_sym] = source.send(a); memo }
  end
end


text:
package gov.va.med.imaging.vistaimagingdatasource;

import gov.va.med.RoutingToken;
import gov.va.med.imaging.artifactsource.ResolvedArtifactSource;
import gov.va.med.imaging.core.interfaces.exceptions.ConnectionException;
import gov.va.med.imaging.core.interfaces.exceptions.MethodException;
import gov.va.med.imaging.transactioncontext.TransactionContextFactory;
import gov.va.med.imaging.vistadatasource.common.VistaCommonUtilities;
import gov.va.med.imaging.vistaimagingdatasource.common.VistaImagingCommonUtilities;

/**
 * An implementation of a VistaRadDataSourceSpi that talks to VistA.
 *
 * NOTE: 1.) public methods that do Vista access (particularly anything defined
 * in the VistaRadDataSourceSpi interface) must acquire a VistaSession instance
 * using getVistaSession(). 2.) private methods which are only called from
 * public methods that do Vista access must include a VistaSession parameter,
 * they should not acquire their own VistaSession 3.) Where a method is both
 * public and called from within this class, there should be a public version
 * following rule 1, calling a private version following rule 2.
 *
 * @author vhaiswlouthj
 * @deprecated This version is no longer supported - Patch 101 is too old
 *
 */
@Deprecated
public class VistaImagingVistaRadDataSourceServiceV0
extends AbstractBaseVistaImagingVistaRadService
{
	/*
	 * =====================================================================
	 * Instance fields and methods
	 * =====================================================================
	 */
	// The required version of VistA Imaging needed to execute the RPC calls for
	// this operation
	public final static String MAG_REQUIRED_VERSION = "3.0.101|VIX";

    /**
	 * @param resolvedArtifactSource
	 * @param protocol
	 */
	public VistaImagingVistaRadDataSourceServiceV0(ResolvedArtifactSource resolvedArtifactSource, String protocol)
	{
		super(resolvedArtifactSource, protocol);
	}

	/* (non-Javadoc)
	 * @see gov.va.med.imaging.vistadatasource.AbstractBaseVistaStudyGraphService#getRequiredVistaImagingVersion()
	 */
	@Override
	protected String getRequiredVistaImagingVersion()
	{
		return VistaImagingCommonUtilities.getVistaDataSourceImagingVersion(
				VistaImagingDataSourceProvider.getVistaConfiguration(), this.getClass(),
				MAG_REQUIRED_VERSION);
	}

	/* (non-Javadoc)
	 * @see gov.va.med.imaging.datasource.VistaRadDataSource#postExamAccessEvent(java.lang.String)
	 */
	@Override
	public boolean postExamAccessEvent(RoutingToken globalRoutingToken, String inputParameter)
	throws MethodException, ConnectionException
	{
		VistaCommonUtilities.setDataSourceMethodAndVersion("postExamAccessEvent", getDataSourceVersion());
		getLogger().info("postExamAccessEvent(" + inputParameter + ") TransactionContext (" + TransactionContextFactory.get().getDisplayIdentity() + ").");

		getLogger().warn("This version of the interface does not support logging, not doing anything.");
		return false;
	}

	@Override
	protected String getDataSourceVersion()
	{
		return "0";
	}
}


text:
'use strict';

var util = require( '../util' );

var corefn = ({

  renderTo: function( context, zoom, pan, pxRatio ){
    var r = this._private.renderer;

    r.renderTo( context, zoom, pan, pxRatio );
    return this;
  },

  renderer: function(){
    return this._private.renderer;
  },

  forceRender: function(){
    this.notify( {
      type: 'draw'
    } );

    return this;
  },

  resize: function(){
    this.invalidateSize();

    this.notify( {
      type: 'resize'
    } );

    this.trigger( 'resize' );

    return this;
  },

  initRenderer: function( options ){
    var cy = this;

    var RendererProto = cy.extension( 'renderer', options.name );
    if( RendererProto == null ){
      util.error( 'Can not initialise: No such renderer `%s` found; did you include its JS file?', options.name );
      return;
    }

    var rOpts = util.extend( {}, options, {
      cy: cy
    } );

    cy._private.renderer = new RendererProto( rOpts );
  },

  destroyRenderer: function(){
    var cy = this;

    cy.notify( { type: 'destroy' } ); // destroy the renderer

    var domEle = cy.container();
    if( domEle ){
      domEle._cyreg = null;

      while( domEle.childNodes.length > 0 ){
        domEle.removeChild( domEle.childNodes[0] );
      }
    }

    cy._private.renderer = null; // to be extra safe, remove the ref
  },

  onRender: function( fn ){
    return this.on('render', fn);
  },

  offRender: function( fn ){
    return this.off('render', fn);
  }

});

corefn.invalidateDimensions = corefn.resize;

module.exports = corefn;


text:
@interface FlightNoViewController : UIViewController

@property (nonatomic,strong) UIButton *timeBtn;

@end


text:
<?xml version="1.0"?>
<!--
  ~ Copyright (c) 2014 Michael Krotscheck
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License"); you may not
  ~ use this file except in compliance with the License. You may obtain a copy
  ~ of the License at
  ~
  ~ http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  ~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->

<!DOCTYPE module PUBLIC
        "-//Puppy Crawl//DTD Check Configuration 1.2//EN"
        "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
<module name="Checker">

    <!-- Checks that each Java package has a Javadoc file used for commenting. -->
    <module name="JavadocPackage">
        <property name="allowLegacy" value="true"/>
    </module>

    <!-- Checks whether files end with a new line.                        -->
    <module name="NewlineAtEndOfFile"/>

    <!-- Checks that property files contain the same keys.         -->
    <module name="Translation"/>
    <module name="FileLength"/>

    <!-- Following interprets the header file as regular expressions. -->
    <module name="FileTabCharacter">
        <property name="eachLine" value="true"/>
    </module>

    <module name="RegexpSingleline">
        <property name="format" value="\s+$"/>
        <property name="message" value="Line has trailing spaces."/>
    </module>

    <module name="TreeWalker">

        <property name="cacheFile" value="${checkstyle.cache.file}"/>

        <!-- Checks for Javadoc comments.                     -->
        <module name="JavadocMethod"/>
        <module name="JavadocType"/>
        <module name="JavadocVariable"/>
        <module name="JavadocStyle"/>

        <!-- Checks for Naming Conventions.                  -->
        <module name="ConstantName"/>
        <module name="LocalFinalVariableName"/>
        <module name="LocalVariableName"/>
        <module name="MemberName"/>
        <module name="MethodName"/>
        <module name="PackageName"/>
        <module name="ParameterName"/>
        <module name="StaticVariableName"/>
        <module name="TypeName"/>

        <!-- Checks for imports                              -->
        <module name="AvoidStarImport"/>
        <module name="IllegalImport"/> <!-- defaults to sun.* packages -->
        <module name="RedundantImport"/>
        <module name="UnusedImports"/>

        <!-- Checks for Size Violations.                    -->
        <module name="LineLength"/>
        <module name="MethodLength"/>
        <module name="ParameterNumber"/>

        <!-- Checks for whitespace                               -->
        <module name="EmptyForIteratorPad"/>
        <module name="MethodParamPad"/>
        <module name="NoWhitespaceAfter"/>
        <module name="NoWhitespaceBefore"/>
        <module name="OperatorWrap"/>
        <module name="ParenPad"/>
        <module name="TypecastParenPad"/>
        <module name="WhitespaceAfter"/>
        <module name="WhitespaceAround"/>

        <!-- Modifier Checks                                    -->
        <module name="ModifierOrder"/>
        <module name="RedundantModifier"/>

        <!-- Checks for blocks. You know, those {}'s         -->
        <module name="AvoidNestedBlocks"/>
        <module name="EmptyBlock"/>
        <module name="LeftCurly"/>
        <module name="NeedBraces"/>
        <module name="RightCurly"/>

        <!-- Checks for common coding problems               -->
        <module name="AvoidInlineConditionals"/>
        <module name="EmptyStatement"/>
        <module name="EqualsHashCode"/>
        <module name="HiddenField"/>
        <module name="IllegalInstantiation"/>
        <module name="InnerAssignment"/>
        <!--<module name="MagicNumber"/>-->
        <module name="MissingSwitchDefault"/>
        <module name="RedundantThrows"/>
        <module name="SimplifyBooleanExpression"/>
        <module name="SimplifyBooleanReturn"/>

        <!-- Checks for class design                         -->
        <module name="DesignForExtension"/>
        <module name="FinalClass"/>
        <module name="HideUtilityClassConstructor"/>
        <module name="InterfaceIsType"/>
        <module name="VisibilityModifier"/>

        <!-- Miscellaneous other checks.                   -->
        <module name="ArrayTypeStyle"/>
        <module name="FinalParameters"/>
        <module name="TodoComment"/>
        <module name="UpperEll"/>

    </module>

</module>


text:
Test opera W3C test suite(http://w3c-test.org/webappsec/tests/cors/submitted/opera/staging/redirect-origin.htm) test case 13 for redirection.

Request URL origin is not same origin with the original URL origin. Final response contains "Access-Control-Allow-Origin: null". Should print PASS.


text:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;

/// <summary>
/// Settings controller.
/// Controls the display and input of
/// configurable settings at runtime.
/// </summary>
public class SettingsController : MonoBehaviour
{
	public GameObject Panel;
	public InputField InitialLivesField;
	public Button SaveButton;
	public Button CloseButton;
	public GameObject ConfigurationPrefab;
	private ConfigurableSettings settings;

	/// <summary>
	/// Start this instance.
	/// </summary>
	private void Start ()
	{
		settings = ConfigurationPrefab.GetComponent<ConfigurableSettings> ();
		SaveButton.onClick.AddListener (() => SaveButtonClick ());
		CloseButton.onClick.AddListener (() => CloseSettingsPanel ());
		InitialLivesField.text = settings.InitialLives.ToString ();
	}

	/// <summary>
	/// Save button click handler.
	/// </summary>
	private void SaveButtonClick ()
	{
		string value = InitialLivesField.text;
		int numLives;
		if (int.TryParse (value, out numLives)) {
			settings.InitialLives = numLives;
		} else {
			InitialLivesField.text = settings.InitialLives.ToString ();
		}
		CloseSettingsPanel ();
	}

	/// <summary>
	/// Closes the settings panel.
	/// </summary>
	public void CloseSettingsPanel ()
	{
		Panel.SetActive (false);
	}

	/// <summary>
	/// Opens the settings panel.
	/// </summary>
	public void OpenSettingsPanel ()
	{
		Panel.SetActive (true);
	}
}


text:
Rich Text Editor Change History
===============================

3.18.1
------

* No changes.

3.18.0
------

* [#1895][]: Fixed an issue with backspace breaks on Chrome and Safari. (@macjohnny)

[#1895]: https://github.com/yui/yui3/pull/1895

3.17.2
------

* No changes.

3.17.1
------

* No changes.

3.17.0
------

* Increase specificity of when to set cursor.
* Check for the existence of `node` before removing it.

3.16.0
------

* Fixed an issue where the `yui-cursor` selector was used as an `id` instead of a `class`. ([#1648][]: @alaaibrahim)

[#1648]: https://github.com/yui/yui3/pull/1648

3.15.0
------

* No changes.

3.14.1
------

* Resolution of several issues in IE 11. ([#1505][]: @ezequiel)

[#1505]: https://github.com/yui/yui3/issues/1505

3.14.0
------

* Fix Y.Frame issue where the linked CSS in the frame was trying to call
  `/undefined`. ([#1367][]: @ipeychev)

[#1367]: https://github.com/yui/yui3/issues/1367

3.13.0
------
* Add in `getEditorOffset` to calculate distance from current selection to the
  beginning of the editor. [Pull Request #1232]

* Editor is able to work in two modes - as an Inline Editor or using an iframe.
  For that reason, some internal changes have been made:

  Y.Frame is now a plugin and extends Y.Plugin.Base.

  There is a new Plugin, called ContentEditable. This plugin allows
  editor to work without using an iframe, as an inline editor.

  If a container is not specified, EditorBase creates and plugs an instance of
  Y.Frame. Otherwise, it uses the provided container (ContentEditable)

  Added Y.InlineEditor which extends EditorBase and plugs ContentEditable
  during the initialization process.

  [Ticket #1041] [ipeychev]

3.12.0
------

* No changes.

3.11.0
------

* Fix exception when sel.anchorNode doesn't exist. [rgrove]

3.10.3
------

* No changes.

3.10.2
------

* No changes.

3.10.1
------

* No changes.

3.10.0
------

* No changes.

3.9.1
-----

* No changes.

3.9.0
-----

* Removed unused `substitute` dependency.

3.8.1
-----

* No changes.

3.8.0
-----

* No changes

3.7.3
-----

* 2532807 fixed regex for ie10
* Converted some tests to work in IE10 better
* Convert innerHTML iframe creation to DOM for IE 10
* Should completely pass lint now

3.7.2
-----

* No changes.

3.7.1
-----

* No changes.

3.7.0
-----

* No changes.

3.6.0
-----

* 2532376 bz #5540030 - Indent/Outdent button doestn't work properly in Chrome/IE when in RTL mode
* 2532395 nodeChange event's command key loses both the underline and strikethrough property if both are appli...

3.5.1
-----

  * No changes.

3.5.0
-----

* 2530547 Frame: src attribute doesn't do anything
* General fixes for Y! Mail deployment
* 2531299 Pressing Backspace may cause editor to lose focus.
* 2531301 Editor using EditorPara and EditorLIsts has JS exceptions
* 2530547 Frame: src attribute doesn't do anything
* 2531329 Rename Y.Selection to Y.EditorSelection (or something)
* 2531577 Plugin.EditorBR works incorrectly in IE
* 2531615 Newline breaks <br> replaced with <wbr> in IE8 [bz 5242614]
* 2531329 - Breaking change, more below:

Bug #2531329 changed the old Y.Selection to Y.EditorSelection. This has been aliased until 3.6.0, bug #2531659
created to track that change.

3.4.1
-----

No changes.

3.4.0
-----

Third release of EditorBase. Considerable work was done on this component, but there are no
public tickets associated with the issues that were resolved. This version of EditorBase is the
current version being used in the new Yahoo! Mail. It's production stable and ready to be used with
the proper skins and GUI.

3.3.0
-----

Second release of EditorBase. Considerable work was done on this component, but there are no
public tickets associated with the issues that were resolved.

3.2.0
-----

Initial Release

This release is a core utility release, the Editor instance that is created contains no GUI.
It's only the iframe rendering and event system.


text:
package no.cantara.csdb.cs_application.commands;

import no.cantara.csdb.util.basecommands.BaseGetCommand;

public class CommandGetArtifactIdByConfigId extends BaseGetCommand<String> {

	String configId;

	public CommandGetArtifactIdByConfigId(String configId){
		super();
		this.configId = configId;
	}

	@Override
	protected String getTargetPath() {
		return "application/config/findartifactid/" + configId;
	}
}


text:
module Azure::SQL::Mgmt::V2015_05_01_preview
  module Models
    #
    # Properties of an Azure SQL Database sync group log.
    #
    class SyncGroupLogProperties

      include MsRestAzure

      # @return [DateTime] Timestamp of the sync group log.
      attr_accessor :timestamp

      # @return [SyncGroupLogType] Type of the sync group log. Possible values
      # include: 'All', 'Error', 'Warning', 'Success'
      attr_accessor :type

      # @return [String] Source of the sync group log.
      attr_accessor :source

      # @return [String] Details of the sync group log.
      attr_accessor :details

      # @return TracingId of the sync group log.
      attr_accessor :tracing_id

      # @return [String] OperationStatus of the sync group log.
      attr_accessor :operation_status

      #
      # Mapper for SyncGroupLogProperties class as Ruby Hash.
      # This will be used for serialization/deserialization.
      #
      def self.mapper()
        {
          client_side_validation: true,
          required: false,
          serialized_name: 'SyncGroupLogProperties',
          type: {
            name: 'Composite',
            class_name: 'SyncGroupLogProperties',
            model_properties: {
              timestamp: {
                client_side_validation: true,
                required: false,
                read_only: true,
                serialized_name: 'timestamp',
                type: {
                  name: 'DateTime'
                }
              },
              type: {
                client_side_validation: true,
                required: false,
                read_only: true,
                serialized_name: 'type',
                type: {
                  name: 'String'
                }
              },
              source: {
                client_side_validation: true,
                required: false,
                read_only: true,
                serialized_name: 'source',
                type: {
                  name: 'String'
                }
              },
              details: {
                client_side_validation: true,
                required: false,
                read_only: true,
                serialized_name: 'details',
                type: {
                  name: 'String'
                }
              },
              tracing_id: {
                client_side_validation: true,
                required: false,
                read_only: true,
                serialized_name: 'tracingId',
                type: {
                  name: 'String'
                }
              },
              operation_status: {
                client_side_validation: true,
                required: false,
                read_only: true,
                serialized_name: 'operationStatus',
                type: {
                  name: 'String'
                }
              }
            }
          }
        }
      end
    end
  end
end


text:
package org.apache.bookkeeper.test;

import java.util.ArrayList;
import java.util.Collection;

import org.apache.bookkeeper.client.BookKeeper.DigestType;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/**
 * Running test case using different ledger managers.
 */
@RunWith(Parameterized.class)
public abstract class MultiLedgerManagerMultiDigestTestCase extends BookKeeperClusterTestCase {
    static final Logger LOG = LoggerFactory.getLogger(MultiLedgerManagerMultiDigestTestCase.class);

    public MultiLedgerManagerMultiDigestTestCase(int numBookies) {
        super(numBookies);
    }

    @Parameters
    public static Collection<Object[]> configs() {
        String[] ledgerManagers = {
            "org.apache.bookkeeper.meta.FlatLedgerManagerFactory",
            "org.apache.bookkeeper.meta.HierarchicalLedgerManagerFactory",
            "org.apache.bookkeeper.meta.MSLedgerManagerFactory",
        };
        ArrayList<Object[]> cfgs = new ArrayList<Object[]>(ledgerManagers.length);
        DigestType[] digestTypes = new DigestType[] { DigestType.MAC, DigestType.CRC32 };
        for (String lm : ledgerManagers) {
            for (DigestType type : digestTypes) {
                cfgs.add(new Object[] { lm, type });
            }
        }
        return cfgs;
    }

}