text:
package com.google.devtools.kythe.analyzers.java;

import com.google.common.base.Ascii;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.Lists;
import com.google.common.collect.Streams;
import com.google.common.flogger.FluentLogger;
import com.google.common.io.ByteStreams;
import com.google.devtools.kythe.analyzers.base.EdgeKind;
import com.google.devtools.kythe.analyzers.base.EntrySet;
import com.google.devtools.kythe.analyzers.java.SourceText.Comment;
import com.google.devtools.kythe.analyzers.java.SourceText.Keyword;
import com.google.devtools.kythe.analyzers.java.SourceText.Positions;
import com.google.devtools.kythe.analyzers.jvm.JvmGraph;
import com.google.devtools.kythe.analyzers.jvm.JvmGraph.Type.ReferenceType;
import com.google.devtools.kythe.platform.java.filemanager.JavaFileStoreBasedFileManager;
import com.google.devtools.kythe.platform.java.helpers.JCTreeScanner;
import com.google.devtools.kythe.platform.java.helpers.JavacUtil;
import com.google.devtools.kythe.platform.java.helpers.SignatureGenerator;
import com.google.devtools.kythe.platform.shared.Metadata;
import com.google.devtools.kythe.platform.shared.MetadataLoaders;
import com.google.devtools.kythe.platform.shared.StatisticsCollector;
import com.google.devtools.kythe.proto.Diagnostic;
import com.google.devtools.kythe.proto.MarkedSource;
import com.google.devtools.kythe.proto.Storage.VName;
import com.google.devtools.kythe.util.Span;
import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
import com.sun.source.tree.Tree.Kind;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.TypeTag;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree;
import com.sun.tools.javac.tree.JCTree.JCAssert;
import com.sun.tools.javac.tree.JCTree.JCAssign;
import com.sun.tools.javac.tree.JCTree.JCAssignOp;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCExpressionStatement;
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCIdent;
import com.sun.tools.javac.tree.JCTree.JCImport;
import com.sun.tools.javac.tree.JCTree.JCLambda;
import com.sun.tools.javac.tree.JCTree.JCLiteral;
import com.sun.tools.javac.tree.JCTree.JCMemberReference;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
import com.sun.tools.javac.tree.JCTree.JCNewClass;
import com.sun.tools.javac.tree.JCTree.JCPackageDecl;
import com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree;
import com.sun.tools.javac.tree.JCTree.JCReturn;
import com.sun.tools.javac.tree.JCTree.JCThrow;
import com.sun.tools.javac.tree.JCTree.JCTypeApply;
import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.tree.JCTree.JCWildcard;
import com.sun.tools.javac.util.Context;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.Name;
import javax.lang.model.element.NestingKind;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;

/** {@link JCTreeScanner} that emits Kythe nodes and edges. */
public class KytheTreeScanner extends JCTreeScanner<JavaNode, TreeContext> {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  /** Maximum allowed text size for variable {@link MarkedSource.Kind.INITIALIZER}s */
  private static final int MAX_INITIALIZER_LENGTH = 80;

  /** Name for special source file containing package annotations and documentation. */
  private static final String PACKAGE_INFO_NAME = "package-info";

  private final JavaIndexerConfig config;

  private final JavaEntrySets entrySets;
  private final StatisticsCollector statistics;
  // TODO(schroederc): refactor SignatureGenerator for new schema names
  private final SignatureGenerator signatureGenerator;
  private final Positions filePositions;
  private final Map<Integer, List<Comment>> comments = new HashMap<>();
  private final Map<Integer, Integer> commentClaims = new HashMap<>();
  private final BiConsumer<JCTree, VName> nodeConsumer;
  private final Context javaContext;
  private final JavaFileStoreBasedFileManager fileManager;
  private final MetadataLoaders metadataLoaders;
  private final JvmGraph jvmGraph;
  private List<Metadata> metadata;

  private KytheDocTreeScanner docScanner;

  private KytheTreeScanner(
      JavaEntrySets entrySets,
      StatisticsCollector statistics,
      SignatureGenerator signatureGenerator,
      SourceText src,
      Context javaContext,
      BiConsumer<JCTree, VName> nodeConsumer,
      JavaFileStoreBasedFileManager fileManager,
      MetadataLoaders metadataLoaders,
      JvmGraph jvmGraph,
      JavaIndexerConfig config) {
    this.entrySets = entrySets;
    this.statistics = statistics;
    this.signatureGenerator = signatureGenerator;
    this.filePositions = src.getPositions();
    this.javaContext = javaContext;
    this.nodeConsumer = nodeConsumer;
    this.fileManager = fileManager;
    this.metadataLoaders = metadataLoaders;
    this.jvmGraph = jvmGraph;
    this.config = config;

    for (Comment comment : src.getComments()) {
      for (int line = comment.lineSpan.getStart(); line <= comment.lineSpan.getEnd(); line++) {
        if (comments.containsKey(line)) {
          comments.get(line).add(comment);
        } else {
          comments.put(line, Lists.newArrayList(comment));
        }
      }
    }
  }

  public static void emitEntries(
      Context javaContext,
      StatisticsCollector statistics,
      JavaEntrySets entrySets,
      SignatureGenerator signatureGenerator,
      JCCompilationUnit compilation,
      BiConsumer<JCTree, VName> nodeConsumer,
      SourceText src,
      JavaFileStoreBasedFileManager fileManager,
      MetadataLoaders metadataLoaders,
      JavaIndexerConfig config)
      throws IOException {
    new KytheTreeScanner(
            entrySets,
            statistics,
            signatureGenerator,
            src,
            javaContext,
            nodeConsumer,
            fileManager,
            metadataLoaders,
            config.getJvmMode() == JavaIndexerConfig.JvmMode.SEMANTIC
                ? new JvmGraph(statistics, entrySets.getEmitter())
                : null,
            config)
        .scan(compilation, null);
  }

  /** Returns the {@link Symtab} (symbol table) for the compilation currently being processed. */
  public Symtab getSymbols() {
    return Symtab.instance(javaContext);
  }

  @Override
  public JavaNode scan(JCTree tree, TreeContext owner) {
    JavaNode node = super.scan(tree, owner);
    if (node != null && nodeConsumer != null) {
      nodeConsumer.accept(tree, node.getVName());
    }
    return node;
  }

  @Override
  public JavaNode visitTopLevel(JCCompilationUnit compilation, TreeContext owner) {
    if (compilation.docComments != null) {
      docScanner = new KytheDocTreeScanner(this, javaContext);
    }
    TreeContext ctx = new TreeContext(filePositions, compilation);
    metadata = Lists.newArrayList();

    EntrySet fileNode = entrySets.newFileNodeAndEmit(filePositions);

    List<JavaNode> decls = scanList(compilation.getTypeDecls(), ctx);
    decls.removeAll(Collections.singleton(null));

    JavaNode pkgNode = scan(compilation.getPackage(), ctx);
    if (pkgNode != null) {
      for (JavaNode n : decls) {
        entrySets.emitEdge(n.getVName(), EdgeKind.CHILDOF, pkgNode.getVName());
      }
    }

    scan(compilation.getImports(), ctx);
    return new JavaNode(fileNode);
  }

  @Override
  public JavaNode visitPackage(JCPackageDecl pkg, TreeContext owner) {
    TreeContext ctx = owner.down(pkg.pid);

    VName pkgNode = entrySets.newPackageNodeAndEmit(pkg.packge).getVName();

    boolean isPkgInfo =
        filePositions
            .getSourceFile()
            .isNameCompatible(PACKAGE_INFO_NAME, JavaFileObject.Kind.SOURCE);
    EdgeKind anchorKind = isPkgInfo ? EdgeKind.DEFINES_BINDING : EdgeKind.REF;
    emitAnchor(ctx, anchorKind, pkgNode);

    visitDocComment(pkgNode, null);
    visitAnnotations(pkgNode, pkg.getAnnotations(), ctx);

    return new JavaNode(pkgNode);
  }

  @Override
  public JavaNode visitImport(JCImport imprt, TreeContext owner) {
    return scan(imprt.qualid, owner.downAsSnippet(imprt));
  }

  @Override
  public JavaNode visitIdent(JCIdent ident, TreeContext owner) {
    return emitSymUsage(owner.down(ident), ident.sym);
  }

  @Override
  public JavaNode visitClassDef(JCClassDecl classDef, TreeContext owner) {
    loadAnnotationsFromClassDecl(classDef);
    TreeContext ctx = owner.down(classDef);

    Optional<String> signature = signatureGenerator.getSignature(classDef.sym);
    if (!signature.isPresent()) {
      // TODO(schroederc): details
      return emitDiagnostic(ctx, "missing class signature", null, null);
    }

    MarkedSource.Builder markedSource = MarkedSource.newBuilder();
    VName classNode =
        entrySets.getNode(signatureGenerator, classDef.sym, signature.get(), markedSource, null);

    // Emit the fact that the class is a child of its containing class or method.
    // Note that for a nested/inner class, we already emitted the fact that it's a
    // child of the containing class when we scanned the containing class's members.
    // However we can't restrict ourselves to just classes contained in methods here,
    // because that would miss the case of local/anonymous classes in static/member
    // initializers. But there's no harm in emitting the same fact twice!
    getScope(ctx).ifPresent(scope -> entrySets.emitEdge(classNode, EdgeKind.CHILDOF, scope));

    NestingKind nestingKind = classDef.sym.getNestingKind();
    if (nestingKind != NestingKind.LOCAL && nestingKind != NestingKind.ANONYMOUS) {
      if (jvmGraph != null) {
        // Emit corresponding JVM node
        JvmGraph.Type.ReferenceType referenceType =
            JvmGraph.Type.referenceType(classDef.sym.fullname.toString());
        VName jvmNode = jvmGraph.emitClassNode(referenceType);
        entrySets.emitEdge(classNode, EdgeKind.GENERATES, jvmNode);
      } else {
        // Emit NAME nodes for the jvm binary name of classes.
        VName nameNode = entrySets.getJvmNameAndEmit(classDef.sym.flatname.toString()).getVName();
        entrySets.emitEdge(classNode, EdgeKind.NAMED, nameNode);
      }
    }

    Span classIdent = filePositions.findIdentifier(classDef.name, classDef.getPreferredPosition());
    if (!classDef.name.isEmpty() && classIdent == null) {
      logger.atWarning().log("Missing span for class identifier: %s", classDef.sym);
    }

    // Generic classes record the source range of the class name for the abs node, regular
    // classes record the source range of the class name for the record node.
    EntrySet absNode =
        defineTypeParameters(
            ctx,
            classNode,
            classDef.getTypeParameters(),
            ImmutableList.<VName>of(), /* There are no wildcards in class definitions */
            markedSource.build());

    boolean documented = visitDocComment(classNode, absNode);

    if (absNode != null) {
      List<String> tParamNames = new ArrayList<>();
      for (JCTypeParameter tParam : classDef.getTypeParameters()) {
        tParamNames.add(tParam.getName().toString());
      }
      if (classIdent != null) {
        EntrySet absAnchor =
            entrySets.newAnchorAndEmit(filePositions, classIdent, ctx.getSnippet());
        emitDefinesBindingEdge(classIdent, absAnchor, absNode.getVName(), getScope(ctx));
      }
      if (!documented) {
        emitComment(classDef, absNode.getVName());
      }
    }
    if (absNode == null && classIdent != null) {
      EntrySet anchor = entrySets.newAnchorAndEmit(filePositions, classIdent, ctx.getSnippet());
      emitDefinesBindingEdge(classIdent, anchor, classNode, getScope(ctx));
    }
    emitAnchor(ctx, EdgeKind.DEFINES, classNode);
    if (!documented) {
      emitComment(classDef, classNode);
    }

    visitAnnotations(classNode, classDef.getModifiers().getAnnotations(), ctx);

    JavaNode superClassNode = scan(classDef.getExtendsClause(), ctx);
    if (superClassNode == null) {
      // Use the implicit superclass.
      switch (classDef.getKind()) {
        case CLASS:
          superClassNode = getJavaLangObjectNode();
          break;
        case ENUM:
          superClassNode = getJavaLangEnumNode(classNode);
          break;
        case ANNOTATION_TYPE:
          // TODO(schroederc): handle annotation superclass
          break;
        case INTERFACE:
          break; // Interfaces have no implicit superclass.
        default:
          logger.atWarning().log("Unexpected JCClassDecl kind: %s", classDef.getKind());
          break;
      }
    }

    if (superClassNode != null) {
      entrySets.emitEdge(classNode, EdgeKind.EXTENDS, superClassNode.getVName());
    }

    for (JCExpression implClass : classDef.getImplementsClause()) {
      JavaNode implNode = scan(implClass, ctx);
      if (implNode == null) {
        statistics.incrementCounter("warning-missing-implements-node");
        logger.atWarning().log(
            "Missing 'implements' node for %s: %s", implClass.getClass(), implClass);
        continue;
      }
      entrySets.emitEdge(classNode, EdgeKind.EXTENDS, implNode.getVName());
    }

    // Set the resulting node for the class before recursing through its members.  Setting the node
    // first is necessary to correctly add childof edges from local/anonymous classes defined
    // directly in the class body (in static initializers or member initializers).
    JavaNode node = ctx.setNode(new JavaNode(classNode));

    for (JCTree member : classDef.getMembers()) {
      JavaNode n = scan(member, ctx);
      if (n != null) {
        entrySets.emitEdge(n.getVName(), EdgeKind.CHILDOF, classNode);
      }
    }

    return node;
  }

  @Override
  public JavaNode visitMethodDef(JCMethodDecl methodDef, TreeContext owner) {
    TreeContext ctx = owner.down(methodDef);

    scan(methodDef.getThrows(), ctx);

    JavaNode returnType = scan(methodDef.getReturnType(), ctx);
    List<JavaNode> params = new ArrayList<>();
    List<JavaNode> paramTypes = new ArrayList<>();
    List<VName> wildcards = new ArrayList<>();
    for (JCVariableDecl param : methodDef.getParameters()) {
      JavaNode n = scan(param, ctx);
      params.add(n);

      JavaNode typeNode = n.getType();
      if (typeNode == null) {
        logger.atWarning().log(
            "Missing parameter type (method: %s; parameter: %s)", methodDef.getName(), param);
        wildcards.addAll(n.childWildcards);
        continue;
      }
      wildcards.addAll(typeNode.childWildcards);
      paramTypes.add(typeNode);
    }

    Optional<String> signature = signatureGenerator.getSignature(methodDef.sym);
    if (!signature.isPresent()) {
      // Try to scan method body even if signature could not be generated.
      scan(methodDef.getBody(), ctx);

      // TODO(schroederc): details
      return emitDiagnostic(ctx, "missing method signature", null, null);
    }

    MarkedSource.Builder markedSource = MarkedSource.newBuilder();
    VName methodNode =
        entrySets.getNode(signatureGenerator, methodDef.sym, signature.get(), markedSource, null);
    visitAnnotations(methodNode, methodDef.getModifiers().getAnnotations(), ctx);

    EntrySet absNode =
        defineTypeParameters(
            ctx, methodNode, methodDef.getTypeParameters(), wildcards, markedSource.build());
    boolean documented = visitDocComment(methodNode, absNode);

    // Emit corresponding JVM node
    if (jvmGraph != null) {
      JvmGraph.Type.MethodType methodJvmType = toMethodJvmType(methodDef.type.asMethodType());
      ReferenceType parentClass = JvmGraph.Type.referenceType(owner.getTree().type.toString());
      String methodName = methodDef.name.toString();
      VName jvmNode = jvmGraph.emitMethodNode(parentClass, methodName, methodJvmType);
      entrySets.emitEdge(methodNode, EdgeKind.GENERATES, jvmNode);

      for (int i = 0; i < params.size(); i++) {
        JavaNode param = params.get(i);
        VName paramJvmNode = jvmGraph.emitParameterNode(parentClass, methodName, methodJvmType, i);
        entrySets.emitEdge(param.getVName(), EdgeKind.GENERATES, paramJvmNode);
        entrySets.emitEdge(jvmNode, EdgeKind.PARAM, paramJvmNode, i);
      }
    }

    VName ret = null;
    EntrySet bindingAnchor = null;
    if (methodDef.sym.isConstructor()) {
      // Implicit constructors (those without syntactic definition locations) share the same
      // preferred position as their owned class.  Since implicit constructors don't exist in the
      // file's text, don't generate anchors them by ensuring the constructor's position is ahead
      // of the owner's position.
      if (methodDef.getPreferredPosition() > owner.getTree().getPreferredPosition()) {
        // Use the owner's name (the class name) to find the definition anchor's
        // location because constructors are internally named "<init>".
        bindingAnchor =
            emitDefinesBindingAnchorEdge(
                ctx, methodDef.sym.owner.name, methodDef.getPreferredPosition(), methodNode);
      }
      // Likewise, constructors don't have return types in the Java AST, but
      // Kythe models all functions with return types.  As a solution, we use
      // the class type as the return type for all constructors.
      ret = getNode(methodDef.sym.owner);
    } else {
      bindingAnchor =
          emitDefinesBindingAnchorEdge(
              ctx, methodDef.name, methodDef.getPreferredPosition(), methodNode);
      ret = returnType.getVName();
    }

    if (bindingAnchor != null) {
      if (!documented) {
        emitComment(methodDef, methodNode);
      }
      if (absNode != null) {
        emitAnchor(bindingAnchor, EdgeKind.DEFINES_BINDING, absNode.getVName(), getScope(ctx));
        Span span = filePositions.findIdentifier(methodDef.name, methodDef.getPreferredPosition());
        if (span != null) {
          emitMetadata(span, absNode.getVName());
        }
        if (!documented) {
          emitComment(methodDef, absNode.getVName());
        }
      }
      emitAnchor(ctx, EdgeKind.DEFINES, methodNode);
    }

    emitOrdinalEdges(methodNode, EdgeKind.PARAM, params);
    EntrySet fnTypeNode = entrySets.newFunctionTypeAndEmit(ret, toVNames(paramTypes));
    entrySets.emitEdge(methodNode, EdgeKind.TYPED, fnTypeNode.getVName());

    JavacUtil.visitSuperMethods(
        javaContext,
        methodDef.sym,
        (sym, kind) ->
            entrySets.emitEdge(
                methodNode,
                kind == JavacUtil.OverrideKind.DIRECT
                    ? EdgeKind.OVERRIDES
                    : EdgeKind.OVERRIDES_TRANSITIVE,
                getNode(sym)));

    // Set the resulting node for the method and then recurse through its body.  Setting the node
    // first is necessary to correctly add childof edges in the callgraph.
    JavaNode node = ctx.setNode(new JavaNode(methodNode));
    scan(methodDef.getBody(), ctx);

    for (JavaNode param : params) {
      entrySets.emitEdge(param.getVName(), EdgeKind.CHILDOF, node.getVName());
    }

    return node;
  }

  @Override
  public JavaNode visitLambda(JCLambda lambda, TreeContext owner) {
    TreeContext ctx = owner.down(lambda);
    VName lambdaNode = entrySets.newLambdaAndEmit(filePositions, lambda).getVName();
    emitAnchor(ctx, EdgeKind.DEFINES, lambdaNode);

    for (Type target : lambda.targets) {
      VName targetNode = getNode(target.asElement());
      entrySets.emitEdge(lambdaNode, EdgeKind.EXTENDS, targetNode);
    }

    scan(lambda.body, ctx);
    scanList(lambda.params, ctx);
    return new JavaNode(lambdaNode);
  }

  @Override
  public JavaNode visitVarDef(JCVariableDecl varDef, TreeContext owner) {
    TreeContext ctx = owner.downAsSnippet(varDef);

    Optional<String> signature = signatureGenerator.getSignature(varDef.sym);
    if (!signature.isPresent()) {
      // TODO(schroederc): details
      return emitDiagnostic(ctx, "missing variable signature", null, null);
    }

    List<MarkedSource> markedSourceChildren = new ArrayList<>();
    if (varDef.getInitializer() != null) {
      String initializer = varDef.getInitializer().toString();
      if (initializer.length() <= MAX_INITIALIZER_LENGTH) {
        markedSourceChildren.add(
            MarkedSource.newBuilder()
                .setKind(MarkedSource.Kind.INITIALIZER)
                .setPreText(initializer)
                .build());
      }
    }
    scan(varDef.getInitializer(), ctx);

    VName varNode =
        entrySets.getNode(
            signatureGenerator, varDef.sym, signature.get(), null, markedSourceChildren);
    boolean documented = visitDocComment(varNode, null);
    emitDefinesBindingAnchorEdge(ctx, varDef.name, varDef.getStartPosition(), varNode);
    emitAnchor(ctx, EdgeKind.DEFINES, varNode);
    if (varDef.sym.getKind().isField() && !documented) {
      // emit comments for fields and enumeration constants
      emitComment(varDef, varNode);
    }

    // Emit corresponding JVM node
    if (jvmGraph != null && varDef.sym.getKind().isField()) {
      VName jvmNode =
          jvmGraph.emitFieldNode(
              JvmGraph.Type.referenceType(owner.getTree().type.toString()), varDef.name.toString());
      entrySets.emitEdge(varNode, EdgeKind.GENERATES, jvmNode);
    }

    getScope(ctx).ifPresent(scope -> entrySets.emitEdge(varNode, EdgeKind.CHILDOF, scope));
    visitAnnotations(varNode, varDef.getModifiers().getAnnotations(), ctx);

    if (varDef.getModifiers().getFlags().contains(Modifier.STATIC)) {
      entrySets.getEmitter().emitFact(varNode, "/kythe/tag/static", "");
    }

    JavaNode typeNode = scan(varDef.getType(), ctx);
    if (typeNode != null) {
      entrySets.emitEdge(varNode, EdgeKind.TYPED, typeNode.getVName());
      return new JavaNode(varNode, typeNode.childWildcards).setType(typeNode);
    }

    return new JavaNode(varNode);
  }

  @Override
  public JavaNode visitTypeApply(JCTypeApply tApply, TreeContext owner) {
    TreeContext ctx = owner.down(tApply);

    JavaNode typeCtorNode = scan(tApply.getType(), ctx);
    if (typeCtorNode == null) {
      logger.atWarning().log("Missing type constructor: %s", tApply.getType());
      return emitDiagnostic(ctx, "missing type constructor", null, null);
    }

    List<JavaNode> arguments = scanList(tApply.getTypeArguments(), ctx);
    List<VName> argVNames = new ArrayList<>();
    Builder<VName> childWildcards = ImmutableList.builder();
    for (JavaNode n : arguments) {
      argVNames.add(n.getVName());
      childWildcards.addAll(n.childWildcards);
    }

    EntrySet typeNode = entrySets.newTApplyAndEmit(typeCtorNode.getVName(), argVNames);
    // TODO(salguarnieri) Think about removing this since it isn't something that we have a use for.
    emitAnchor(ctx, EdgeKind.REF, typeNode.getVName());

    return new JavaNode(typeNode, childWildcards.build());
  }

  @Override
  public JavaNode visitSelect(JCFieldAccess field, TreeContext owner) {
    TreeContext ctx = owner.down(field);

    JCImport imprt = null;
    if (owner.getTree() instanceof JCImport) {
      imprt = (JCImport) owner.getTree();
    }

    Symbol sym = field.sym;
    if (sym == null && imprt != null && imprt.isStatic()) {
      // Static imports don't have their symbol populated so we search for the symbol.

      ClassSymbol cls = JavacUtil.getClassSymbol(javaContext, field.selected + "." + field.name);
      if (cls != null) {
        // Import was a inner class import
        sym = cls;
      } else {
        cls = JavacUtil.getClassSymbol(javaContext, field.selected.toString());
        if (cls != null) {
          // Import is a class member; emit usages for all matching (by name) class members.
          ctx = ctx.down(field);
          JavaNode lastMember = null;
          for (Symbol member : cls.members().getSymbolsByName(field.name)) {
            try {
              // Ensure member symbol's type is complete.  If the extractor finds that a static
              // member isn't used (due to overloads), the symbol's dependent type classes won't
              // be saved in the CompilationUnit and this will throw an exception.
              if (member.type != null) {
                member.type.tsym.complete();
                member.type.getParameterTypes().forEach(t -> t.tsym.complete());
                Type returnType = member.type.getReturnType();
                if (returnType != null) {
                  returnType.tsym.complete();
                }
              }

              lastMember = emitNameUsage(ctx, member, field.name, EdgeKind.REF_IMPORTS);
            } catch (Symbol.CompletionFailure e) {
              // Symbol resolution failed (see above comment).  Ignore and continue with other
              // class members matching static import.
            }
          }
          scan(field.getExpression(), ctx);
          return lastMember;
        }
      }
    }

    if (sym == null) {
      scan(field.getExpression(), ctx);
      if (!field.name.toString().equals("*")) {
        String msg = "Could not determine selected Symbol for " + field;
        if (config.getVerboseLogging()) {
          logger.atWarning().log(msg);
        }
        return emitDiagnostic(ctx, msg, null, null);
      }
      return null;
    } else if (sym.getKind() == ElementKind.PACKAGE) {
      EntrySet pkgNode = entrySets.newPackageNodeAndEmit((PackageSymbol) sym);
      emitAnchor(ctx, EdgeKind.REF, pkgNode.getVName());
      return new JavaNode(pkgNode);
    } else {
      scan(field.getExpression(), ctx);
      return emitNameUsage(
          ctx, sym, field.name, imprt != null ? EdgeKind.REF_IMPORTS : EdgeKind.REF);
    }
  }

  @Override
  public JavaNode visitReference(JCMemberReference reference, TreeContext owner) {
    TreeContext ctx = owner.down(reference);
    scan(reference.getQualifierExpression(), ctx);
    return emitNameUsage(
        ctx,
        reference.sym,
        reference.getMode() == ReferenceMode.NEW ? Keyword.of("new") : reference.name);
  }

  @Override
  public JavaNode visitApply(JCMethodInvocation invoke, TreeContext owner) {
    TreeContext ctx = owner.down(invoke);
    scan(invoke.getArguments(), ctx);
    scan(invoke.getTypeArguments(), ctx);

    JavaNode method = scan(invoke.getMethodSelect(), ctx);
    if (method == null) {
      // TODO details
      return emitDiagnostic(ctx, "error analyzing method", null, null);
    }

    emitAnchor(ctx, EdgeKind.REF_CALL, method.getVName());
    return method;
  }

  @Override
  public JavaNode visitNewClass(JCNewClass newClass, TreeContext owner) {
    TreeContext ctx = owner.down(newClass);

    VName ctorNode = getNode(newClass.constructor);
    if (ctorNode == null) {
      return emitDiagnostic(ctx, "error analyzing class", null, null);
    }

    // Span over "new Class"
    Span refSpan =
        new Span(filePositions.getStart(newClass), filePositions.getEnd(newClass.getIdentifier()));
    // Span over "new Class(...)"
    Span callSpan = new Span(refSpan.getStart(), filePositions.getEnd(newClass));

    if (owner.getTree().getTag() == JCTree.Tag.VARDEF) {
      JCVariableDecl varDef = (JCVariableDecl) owner.getTree();
      if (varDef.sym.getKind() == ElementKind.ENUM_CONSTANT) {
        // Handle enum constructors specially.
        // Span over "EnumValueName"
        refSpan = filePositions.findIdentifier(varDef.name, varDef.getStartPosition());
        // Span over "EnumValueName(...)"
        callSpan = new Span(refSpan.getStart(), filePositions.getEnd(varDef));
      }
    }

    EntrySet anchor = entrySets.newAnchorAndEmit(filePositions, refSpan, ctx.getSnippet());
    emitAnchor(anchor, EdgeKind.REF, ctorNode, getScope(ctx));

    EntrySet callAnchor = entrySets.newAnchorAndEmit(filePositions, callSpan, ctx.getSnippet());
    emitAnchor(callAnchor, EdgeKind.REF_CALL, ctorNode, getScope(ctx));

    scanList(newClass.getTypeArguments(), ctx);
    scanList(newClass.getArguments(), ctx);
    scan(newClass.getEnclosingExpression(), ctx);
    scan(newClass.getClassBody(), ctx);
    return scan(newClass.getIdentifier(), ctx);
  }

  @Override
  public JavaNode visitTypeIdent(JCPrimitiveTypeTree primitiveType, TreeContext owner) {
    TreeContext ctx = owner.down(primitiveType);
    if (config.getVerboseLogging() && primitiveType.typetag == TypeTag.ERROR) {
      logger.atWarning().log("found primitive ERROR type: %s", ctx);
    }
    String name = Ascii.toLowerCase(primitiveType.typetag.toString());
    EntrySet node = entrySets.newBuiltinAndEmit(name);
    emitAnchor(ctx, EdgeKind.REF, node.getVName());
    return new JavaNode(node);
  }

  @Override
  public JavaNode visitTypeArray(JCArrayTypeTree arrayType, TreeContext owner) {
    TreeContext ctx = owner.down(arrayType);

    JavaNode typeNode = scan(arrayType.getType(), ctx);
    EntrySet node =
        entrySets.newTApplyAndEmit(
            entrySets.newBuiltinAndEmit("array").getVName(), Arrays.asList(typeNode.getVName()));
    emitAnchor(ctx, EdgeKind.REF, node.getVName());
    JavaNode arrayNode = new JavaNode(node);
    return arrayNode;
  }

  @Override
  public JavaNode visitAnnotation(JCAnnotation annotation, TreeContext owner) {
    TreeContext ctx = owner.down(annotation);
    scanList(annotation.getArguments(), ctx);
    return scan(annotation.getAnnotationType(), ctx);
  }

  @Override
  public JavaNode visitWildcard(JCWildcard wild, TreeContext owner) {
    TreeContext ctx = owner.down(wild);

    EntrySet node = entrySets.newWildcardNodeAndEmit(wild, owner.getSourcePath());
    Builder<VName> wildcards = ImmutableList.builder();
    wildcards.add(node.getVName());

    if (wild.getKind() != Kind.UNBOUNDED_WILDCARD) {
      JavaNode bound = scan(wild.getBound(), ctx);
      emitEdge(
          node,
          wild.getKind() == Kind.EXTENDS_WILDCARD ? EdgeKind.BOUNDED_UPPER : EdgeKind.BOUNDED_LOWER,
          bound);
      wildcards.addAll(bound.childWildcards);
    }
    return new JavaNode(node, wildcards.build());
  }

  @Override
  public JavaNode visitExec(JCExpressionStatement stmt, TreeContext owner) {
    return scan(stmt.expr, owner.downAsSnippet(stmt));
  }

  @Override
  public JavaNode visitReturn(JCReturn ret, TreeContext owner) {
    return scan(ret.expr, owner.downAsSnippet(ret));
  }

  @Override
  public JavaNode visitThrow(JCThrow thr, TreeContext owner) {
    return scan(thr.expr, owner.downAsSnippet(thr));
  }

  @Override
  public JavaNode visitAssert(JCAssert azzert, TreeContext owner) {
    return scanAll(owner.downAsSnippet(azzert), azzert.cond, azzert.detail);
  }

  @Override
  public JavaNode visitAssign(JCAssign assgn, TreeContext owner) {
    return scanAll(owner.downAsSnippet(assgn), assgn.lhs, assgn.rhs);
  }

  @Override
  public JavaNode visitAssignOp(JCAssignOp assgnOp, TreeContext owner) {
    return scanAll(owner.downAsSnippet(assgnOp), assgnOp.lhs, assgnOp.rhs);
  }

  private boolean visitDocComment(VName node, EntrySet absNode) {
    // TODO(https://phabricator-dot-kythe-repo.appspot.com/T185): always use absNode
    return docScanner != null && docScanner.visitDocComment(treePath, node, absNode);
  }

  // // Utility methods ////

  void emitDocReference(Symbol sym, int startChar, int endChar) {
    VName node = getNode(sym);
    if (node == null) {
      if (config.getVerboseLogging()) {
        logger.atWarning().log("failed to emit documentation reference to %s", sym);
      }
      return;
    }

    Span loc =
        new Span(
            filePositions.charToByteOffset(startChar), filePositions.charToByteOffset(endChar));
    EntrySet anchor = entrySets.newAnchorAndEmit(filePositions, loc);
    if (anchor != null) {
      emitAnchor(anchor, EdgeKind.REF_DOC, node, Optional.empty());
    }
  }

  int charToLine(int charPosition) {
    return filePositions.charToLine(charPosition);
  }

  boolean emitCommentsOnLine(int line, VName node, int defLine) {
    List<Comment> lst = comments.get(line);
    if (lst == null || commentClaims.computeIfAbsent(line, l -> defLine) != defLine) {
      return false;
    }
    for (Comment comment : lst) {
      String bracketed =
          MiniAnchor.bracket(
              comment.text.replaceFirst("^(//|/\\*) ?", "").replaceFirst(" ?\\*/$", ""),
              pos -> pos,
              Lists.newArrayList());
      emitDoc(DocKind.LINE, bracketed, Lists.newArrayList(), node, null);
    }
    return !lst.isEmpty();
  }

  private static List<VName> toVNames(Iterable<JavaNode> nodes) {
    return Streams.stream(nodes).map(JavaNode::getVName).collect(Collectors.toList());
  }

  // TODO When we want to refer to a type or method that is generic, we need to point to the abs
  // node. The code currently does not have an easy way to access that node but this method might
  // offer a way to change that.
  // See https://phabricator-dot-kythe-repo.appspot.com/T185 for more discussion and detail.
  /** Create an abs node if we have type variables or if we have wildcards. */
  private EntrySet defineTypeParameters(
      TreeContext ownerContext,
      VName owner,
      List<JCTypeParameter> params,
      List<VName> wildcards,
      MarkedSource markedSource) {
    if (params.isEmpty() && wildcards.isEmpty()) {
      return null;
    }

    List<VName> typeParams = new ArrayList<>();
    for (JCTypeParameter tParam : params) {
      TreeContext ctx = ownerContext.down(tParam);
      VName node = getNode(tParam.type.asElement());
      emitDefinesBindingAnchorEdge(ctx, tParam.name, tParam.getStartPosition(), node);
      visitAnnotations(node, tParam.getAnnotations(), ctx);
      typeParams.add(node);

      List<JCExpression> bounds = tParam.getBounds();
      List<JavaNode> boundNodes =
          bounds.stream().map(expr -> scan(expr, ctx)).collect(Collectors.toList());
      if (boundNodes.isEmpty()) {
        boundNodes.add(getJavaLangObjectNode());
      }
      emitOrdinalEdges(node, EdgeKind.BOUNDED_UPPER, boundNodes);
    }
    // Add all of the wildcards that roll up to this node. For example:
    // public static <T> void foo(Ty<?> a, Obj<?, ?> b, Obj<Ty<?>, Ty<?>> c) should declare an abs
    // node that has 1 named absvar (T) and 5 unnamed absvars.
    typeParams.addAll(wildcards);
    return entrySets.newAbstractAndEmit(owner, typeParams, markedSource);
  }

  /** Returns the node associated with a {@link Symbol} or {@code null}. */
  private VName getNode(Symbol sym) {
    JavaNode node = getJavaNode(sym);
    return node == null ? null : node.getVName();
  }

  /** Returns the {@link JavaNode} associated with a {@link Symbol} or {@code null}. */
  private JavaNode getJavaNode(Symbol sym) {
    Optional<String> signature = signatureGenerator.getSignature(sym);
    if (!signature.isPresent()) {
      return null;
    }
    return new JavaNode(entrySets.getNode(signatureGenerator, sym, signature.get(), null, null));
  }

  private void visitAnnotations(
      VName owner, List<JCAnnotation> annotations, TreeContext ownerContext) {
    for (JavaNode node : scanList(annotations, ownerContext)) {
      entrySets.emitEdge(owner, EdgeKind.ANNOTATED_BY, node.getVName());
    }
  }

  // Emits a node for the given sym, an anchor encompassing the TreeContext, and a REF edge
  private JavaNode emitSymUsage(TreeContext ctx, Symbol sym) {
    JavaNode node = getRefNode(ctx, sym);
    if (node == null) {
      // TODO(schroederc): details
      return emitDiagnostic(ctx, "failed to resolve symbol reference", null, null);
    }

    // TODO(schroederc): emit reference to JVM node if `sym.outermostClass()` is not defined in a
    //                   .java source file
    emitAnchor(ctx, EdgeKind.REF, node.getVName());
    statistics.incrementCounter("symbol-usages-emitted");
    return node;
  }

  // Emits a node for the given sym, an anchor encompassing the name, and a REF edge
  private JavaNode emitNameUsage(TreeContext ctx, Symbol sym, Name name) {
    return emitNameUsage(ctx, sym, name, EdgeKind.REF);
  }

  // Emits a node for the given sym, an anchor encompassing the name, and a given edge kind
  private JavaNode emitNameUsage(TreeContext ctx, Symbol sym, Name name, EdgeKind edgeKind) {
    JavaNode node = getRefNode(ctx, sym);
    if (node == null) {
      // TODO(schroederc): details
      return emitDiagnostic(ctx, "failed to resolve symbol name", null, null);
    }

    // Ensure the context has a valid source span before searching for the Name.  Otherwise, anchors
    // may accidentily be emitted for Names that happen to appear after the tree context (e.g.
    // lambdas with type-inferred parameters that use the parameter type in the lambda body).
    if (filePositions.getSpan(ctx.getTree()).isValid()) {
      emitAnchor(
          name,
          ctx.getTree().getPreferredPosition(),
          edgeKind,
          node.getVName(),
          ctx.getSnippet(),
          getScope(ctx));
      statistics.incrementCounter("name-usages-emitted");
    }
    return node;
  }

  private static Optional<VName> getScope(TreeContext ctx) {
    return Optional.ofNullable(ctx.getClassOrMethodParent())
        .map(TreeContext::getNode)
        .map(JavaNode::getVName);
  }

  // Returns the reference node for the given symbol.
  private JavaNode getRefNode(TreeContext ctx, Symbol sym) {
    // If referencing a generic class, distinguish between generic vs. raw use
    // (e.g., `List` is in generic context in `List<String> x` but not in `List x`).
    boolean inGenericContext = ctx.up().getTree() instanceof JCTypeApply;
    try {
      if (sym != null
          && SignatureGenerator.isArrayHelperClass(sym.enclClass())
          && ctx.getTree() instanceof JCFieldAccess) {
        signatureGenerator.setArrayTypeContext(((JCFieldAccess) ctx.getTree()).selected.type);
      }
      JavaNode node = getJavaNode(sym);
      if (node != null
          && sym instanceof ClassSymbol
          && inGenericContext
          && !sym.getTypeParameters().isEmpty()) {
        // Always reference the abs node of a generic class, unless used as a raw type.
        node = new JavaNode(entrySets.newAbstractAndEmit(node.getVName()));
      }
      return node;
    } finally {
      signatureGenerator.setArrayTypeContext(null);
    }
  }

  // Returns a JavaNode representing java.lang.Object.
  private JavaNode getJavaLangObjectNode() {
    Symbol javaLangObject = getSymbols().objectType.asElement();
    String javaLangObjectSignature = signatureGenerator.getSignature(javaLangObject).get();
    VName javaLangObjectVName =
        entrySets.getNode(signatureGenerator, javaLangObject, javaLangObjectSignature, null, null);
    return new JavaNode(javaLangObjectVName);
  }

  // Returns a JavaNode representing java.lang.Enum<E> where E is a given enum type.
  private JavaNode getJavaLangEnumNode(VName enumVName) {
    Symbol javaLangEnum = getSymbols().enumSym;
    String javaLangEnumSignature = signatureGenerator.getSignature(javaLangEnum).get();
    EntrySet javaLangEnumEntrySet =
        entrySets.newAbstractAndEmit(
            entrySets.getNode(signatureGenerator, javaLangEnum, javaLangEnumSignature, null, null));
    EntrySet typeNode =
        entrySets.newTApplyAndEmit(
            javaLangEnumEntrySet.getVName(), Collections.singletonList(enumVName));
    return new JavaNode(typeNode);
  }

  // Creates/emits an anchor and an associated edge
  private EntrySet emitAnchor(TreeContext anchorContext, EdgeKind kind, VName node) {
    return emitAnchor(
        entrySets.newAnchorAndEmit(
            filePositions, anchorContext.getTreeSpan(), anchorContext.getSnippet()),
        kind,
        node,
        getScope(anchorContext));
  }

  // Creates/emits an anchor (for an identifier) and an associated edge
  private EntrySet emitAnchor(
      Name name, int startOffset, EdgeKind kind, VName node, Span snippet, Optional<VName> scope) {
    EntrySet anchor = entrySets.newAnchorAndEmit(filePositions, name, startOffset, snippet);
    if (anchor == null) {
      // TODO(schroederc): Special-case these anchors (most come from visitSelect)
      return null;
    }
    return emitAnchor(anchor, kind, node, scope);
  }

  private void emitMetadata(Span span, VName node) {
    for (Metadata data : metadata) {
      for (Metadata.Rule rule : data.getRulesForLocation(span.getStart())) {
        if (rule.end == span.getEnd()) {
          if (rule.reverseEdge) {
            entrySets.emitEdge(rule.vname, rule.edgeOut, node);
          } else {
            entrySets.emitEdge(node, rule.edgeOut, rule.vname);
          }
        }
      }
    }
  }

  private EntrySet emitDefinesBindingAnchorEdge(
      TreeContext ctx, Name name, int startOffset, VName node) {
    EntrySet anchor =
        emitAnchor(
            name, startOffset, EdgeKind.DEFINES_BINDING, node, ctx.getSnippet(), getScope(ctx));
    Span span = filePositions.findIdentifier(name, startOffset);
    if (span != null) {
      emitMetadata(span, node);
    }
    return anchor;
  }

  private void emitDefinesBindingEdge(
      Span span, EntrySet anchor, VName node, Optional<VName> scope) {
    emitMetadata(span, node);
    emitAnchor(anchor, EdgeKind.DEFINES_BINDING, node, scope);
  }

  // Creates/emits an anchor and an associated edge
  private EntrySet emitAnchor(EntrySet anchor, EdgeKind kind, VName node, Optional<VName> scope) {
    Preconditions.checkArgument(
        kind.isAnchorEdge(), "EdgeKind was not intended for ANCHORs: %s", kind);
    if (anchor == null) {
      return null;
    }
    entrySets.emitEdge(anchor.getVName(), kind, node);
    if (kind == EdgeKind.REF_CALL || config.getEmitAnchorScopes()) {
      scope.ifPresent(s -> entrySets.emitEdge(anchor.getVName(), EdgeKind.CHILDOF, s));
    }
    return anchor;
  }

  private void emitComment(JCTree defTree, VName node) {
    int defPosition = defTree.getPreferredPosition();
    int defLine = filePositions.charToLine(defPosition);
    emitCommentsOnLine(defLine, node, defLine);
    emitCommentsOnLine(defLine - 1, node, defLine);
  }

  void emitDoc(
      DocKind kind, String bracketedText, Iterable<Symbol> params, VName node, VName absNode) {
    List<VName> paramNodes = Lists.newArrayList();
    for (Symbol s : params) {
      VName paramNode = getNode(s);
      if (paramNode == null) {
        return;
      }
      paramNodes.add(paramNode);
    }
    EntrySet doc =
        entrySets.newDocAndEmit(kind.getDocSubkind(), filePositions, bracketedText, paramNodes);
    // TODO(https://phabricator-dot-kythe-repo.appspot.com/T185): always use absNode
    entrySets.emitEdge(doc.getVName(), EdgeKind.DOCUMENTS, node);
    if (absNode != null) {
      entrySets.emitEdge(doc.getVName(), EdgeKind.DOCUMENTS, absNode);
    }
  }

  // Unwraps the target EntrySet and emits an edge to it from the sourceNode
  private void emitEdge(EntrySet sourceNode, EdgeKind kind, JavaNode target) {
    entrySets.emitEdge(sourceNode.getVName(), kind, target.getVName());
  }

  // Unwraps each target JavaNode and emits an ordinal edge to each from the given source node
  private void emitOrdinalEdges(VName node, EdgeKind kind, List<JavaNode> targets) {
    entrySets.emitOrdinalEdges(node, kind, toVNames(targets));
  }

  private JavaNode emitDiagnostic(TreeContext ctx, String message, String details, String context) {
    Diagnostic.Builder d = Diagnostic.newBuilder().setMessage(message);
    if (details != null) {
      d.setDetails(details);
    }
    if (context != null) {
      d.setContextUrl(context);
    }
    Span s = ctx.getTreeSpan();
    if (s.isValid()) {
      d.getSpanBuilder().getStartBuilder().setByteOffset(s.getStart());
      d.getSpanBuilder().getEndBuilder().setByteOffset(s.getEnd());
    } else if (s.getStart() >= 0) {
      // If the span isn't valid but we have a valid start, use the start for a zero-width span.
      d.getSpanBuilder().getStartBuilder().setByteOffset(s.getStart());
      d.getSpanBuilder().getEndBuilder().setByteOffset(s.getStart());
    }
    EntrySet node = entrySets.emitDiagnostic(filePositions, d.build());
    // TODO(schroederc): don't allow any edges to a diagnostic node
    return new JavaNode(node);
  }

  private <T extends JCTree> List<JavaNode> scanList(List<T> trees, TreeContext owner) {
    List<JavaNode> nodes = new ArrayList<>();
    for (T t : trees) {
      nodes.add(scan(t, owner));
    }
    return nodes;
  }

  private void loadAnnotationsFile(String path) {
    URI uri = filePositions.getSourceFile().toUri();
    try {
      String fullPath = uri.resolve(path).getPath();
      if (fullPath.startsWith("/")) {
        fullPath = fullPath.substring(1);
      }
      FileObject file = fileManager.getJavaFileFromPath(fullPath, JavaFileObject.Kind.OTHER);
      if (file == null) {
        logger.atWarning().log("Can't find metadata %s for %s at %s", path, uri, fullPath);
        return;
      }
      InputStream stream = file.openInputStream();
      Metadata newMetadata = metadataLoaders.parseFile(fullPath, ByteStreams.toByteArray(stream));
      if (newMetadata == null) {
        logger.atWarning().log("Can't load metadata %s for %s", path, uri);
        return;
      }
      metadata.add(newMetadata);
    } catch (IOException | IllegalArgumentException ex) {
      logger.atWarning().log("Can't read metadata %s for %s", path, uri);
    }
  }

  private void loadAnnotationsFromClassDecl(JCClassDecl decl) {
    for (JCAnnotation annotation : decl.getModifiers().getAnnotations()) {
      Symbol annotationSymbol = null;
      if (annotation.getAnnotationType() instanceof JCFieldAccess) {
        annotationSymbol = ((JCFieldAccess) annotation.getAnnotationType()).sym;
      } else if (annotation.getAnnotationType() instanceof JCIdent) {
        annotationSymbol = ((JCIdent) annotation.getAnnotationType()).sym;
      }
      if (annotationSymbol == null
          || !annotationSymbol.toString().equals("javax.annotation.Generated")) {
        continue;
      }
      for (JCExpression arg : annotation.getArguments()) {
        if (!(arg instanceof JCAssign)) {
          continue;
        }
        JCAssign assignArg = (JCAssign) arg;
        if (!(assignArg.lhs instanceof JCIdent) || !(assignArg.rhs instanceof JCLiteral)) {
          continue;
        }
        JCIdent lhs = (JCIdent) assignArg.lhs;
        JCLiteral rhs = (JCLiteral) assignArg.rhs;
        if (!lhs.name.contentEquals("comments") || !(rhs.getValue() instanceof String)) {
          continue;
        }
        String comments = (String) rhs.getValue();
        if (comments.startsWith(Metadata.ANNOTATION_COMMENT_PREFIX)) {
          loadAnnotationsFile(comments.substring(Metadata.ANNOTATION_COMMENT_PREFIX.length()));
        }
      }
    }
  }

  static JvmGraph.Type toJvmType(Type type) {
    switch (type.getTag()) {
      case ARRAY:
        return JvmGraph.Type.arrayType(toJvmType(((Type.ArrayType) type).getComponentType()));
      case CLASS:
        return JvmGraph.Type.referenceType(type.toString());
      case METHOD:
        return toMethodJvmType(type.asMethodType());
      case TYPEVAR:
        return JvmGraph.Type.referenceType("java.lang.Object");

      case BOOLEAN:
        return JvmGraph.Type.booleanType();
      case BYTE:
        return JvmGraph.Type.byteType();
      case CHAR:
        return JvmGraph.Type.charType();
      case DOUBLE:
        return JvmGraph.Type.doubleType();
      case FLOAT:
        return JvmGraph.Type.floatType();
      case INT:
        return JvmGraph.Type.intType();
      case LONG:
        return JvmGraph.Type.longType();
      case SHORT:
        return JvmGraph.Type.shortType();

      default:
        throw new IllegalStateException("unhandled Java Type: " + type.getTag());
    }
  }

  private static JvmGraph.VoidableType toJvmReturnType(Type type) {
    switch (type.getTag()) {
      case VOID:
        return JvmGraph.Type.voidType();
      default:
        return toJvmType(type);
    }
  }

  static JvmGraph.Type.MethodType toMethodJvmType(Type.MethodType type) {
    return JvmGraph.Type.methodType(
        type.getParameterTypes()
            .stream()
            .map(KytheTreeScanner::toJvmType)
            .collect(Collectors.toList()),
        toJvmReturnType(type.getReturnType()));
  }

  static enum DocKind {
    JAVADOC(Optional.of("javadoc")),
    LINE;

    private final Optional<String> subkind;

    private DocKind(Optional<String> subkind) {
      this.subkind = subkind;
    }

    private DocKind() {
      this(Optional.empty());
    }

    /** Returns the Kythe subkind for this type of document. */
    public Optional<String> getDocSubkind() {
      return subkind;
    }
  }
}


text:
package com.google.security.zynamics.reil.translators.mips;

import static org.junit.Assert.assertEquals;

import com.google.common.collect.Lists;
import com.google.security.zynamics.reil.OperandSize;
import com.google.security.zynamics.reil.ReilInstruction;
import com.google.security.zynamics.reil.TestHelpers;
import com.google.security.zynamics.reil.interpreter.CpuPolicyMips;
import com.google.security.zynamics.reil.interpreter.EmptyInterpreterPolicy;
import com.google.security.zynamics.reil.interpreter.Endianness;
import com.google.security.zynamics.reil.interpreter.InterpreterException;
import com.google.security.zynamics.reil.interpreter.ReilInterpreter;
import com.google.security.zynamics.reil.interpreter.ReilRegisterStatus;
import com.google.security.zynamics.reil.translators.InternalTranslationException;
import com.google.security.zynamics.reil.translators.StandardEnvironment;
import com.google.security.zynamics.reil.translators.mips.JalrTranslator;
import com.google.security.zynamics.zylib.disassembly.ExpressionType;
import com.google.security.zynamics.zylib.disassembly.IInstruction;
import com.google.security.zynamics.zylib.disassembly.MockInstruction;
import com.google.security.zynamics.zylib.disassembly.MockOperandTree;
import com.google.security.zynamics.zylib.disassembly.MockOperandTreeNode;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

@RunWith(JUnit4.class)
public class JalrTranslatorTest {
  private final ReilInterpreter interpreter = new ReilInterpreter(Endianness.LITTLE_ENDIAN,
      new CpuPolicyMips(), new EmptyInterpreterPolicy());

  private final StandardEnvironment environment = new StandardEnvironment();

  private final JalrTranslator translator = new JalrTranslator();

  private final ArrayList<ReilInstruction> instructions = new ArrayList<ReilInstruction>();

  @Test
  public void testJalrOneArgument() throws InternalTranslationException, InterpreterException {
    interpreter.setRegister("$t6", BigInteger.valueOf(0x00400018L), OperandSize.DWORD,
        ReilRegisterStatus.DEFINED);

    final MockOperandTree operandTree1 = new MockOperandTree();
    operandTree1.root = new MockOperandTreeNode(ExpressionType.SIZE_PREFIX, "b4");
    operandTree1.root.m_children.add(new MockOperandTreeNode(ExpressionType.REGISTER, "$t6"));

    // final MockOperandTree operandTree2 = new MockOperandTree();
    // operandTree2.root = new MockOperandTreeNode(ExpressionType.SIZE_PREFIX, "b4");
    // operandTree2.root.children.add(new MockOperandTreeNode(ExpressionType.REGISTER, "$ra"));

    final List<MockOperandTree> operands = Lists.newArrayList(operandTree1);// , operandTree2);

    final IInstruction instruction = new MockInstruction(0x00400044L, "jalr", operands);

    translator.translate(environment, instruction, instructions);

    interpreter.interpret(TestHelpers.createMapping(instructions), BigInteger.valueOf(0x00400044L));

    // check correct outcome

    assertEquals(3, TestHelpers.filterNativeRegisters(interpreter.getDefinedRegisters()).size());
    assertEquals(BigInteger.valueOf(0x00400018L), interpreter.getVariableValue("$t6"));
    assertEquals(BigInteger.valueOf(0x00400048L), interpreter.getVariableValue("$ra"));
    assertEquals(BigInteger.valueOf(0x00400018L), interpreter.getVariableValue("$pc"));
    assertEquals(BigInteger.ZERO, BigInteger.valueOf(interpreter.getMemorySize()));
  }

  @Test
  public void testJalrTwoArguments() throws InternalTranslationException, InterpreterException {
    interpreter.setRegister("$t6", BigInteger.valueOf(0x00400018L), OperandSize.DWORD,
        ReilRegisterStatus.DEFINED);
    interpreter.setRegister("$t7", BigInteger.valueOf(0x00000000L), OperandSize.DWORD,
        ReilRegisterStatus.DEFINED);

    final MockOperandTree operandTree1 = new MockOperandTree();
    operandTree1.root = new MockOperandTreeNode(ExpressionType.SIZE_PREFIX, "b4");
    operandTree1.root.m_children.add(new MockOperandTreeNode(ExpressionType.REGISTER, "$t7"));

    final MockOperandTree operandTree2 = new MockOperandTree();
    operandTree2.root = new MockOperandTreeNode(ExpressionType.SIZE_PREFIX, "b4");
    operandTree2.root.m_children.add(new MockOperandTreeNode(ExpressionType.REGISTER, "$t6"));

    final List<MockOperandTree> operands = Lists.newArrayList(operandTree1, operandTree2);

    final IInstruction instruction = new MockInstruction(0x00400044L, "jalr", operands);

    translator.translate(environment, instruction, instructions);

    interpreter.interpret(TestHelpers.createMapping(instructions), BigInteger.valueOf(0x00400044L));

    // check correct outcome

    assertEquals(3, TestHelpers.filterNativeRegisters(interpreter.getDefinedRegisters()).size());
    assertEquals(BigInteger.valueOf(0x00400048L), interpreter.getVariableValue("$t7"));
    assertEquals(BigInteger.valueOf(0x00400018L), interpreter.getVariableValue("$t6"));
    assertEquals(BigInteger.valueOf(0x00400018L), interpreter.getVariableValue("$pc"));
    assertEquals(BigInteger.ZERO, BigInteger.valueOf(interpreter.getMemorySize()));
  }
}

redpajama_set_name: RedPajamaGithub


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Example
{
    class Global
    {
        public const int MAX_NAXIS = 16;
        public static IntPtr g_handle;
        public static int g_naxis;

        private Global()
        {
            g_handle = IntPtr.Zero;
            g_naxis = 0;
        }

        public static bool isOpen()
        {
            return g_handle != IntPtr.Zero;
        }
    }
}


text: Test Browserify


text:
from django import template

from ..models import Message

register = template.Library()

@register.simple_tag(takes_context=True)
def get_messages_for_page(context, url):
    if url == context.template.engine.string_if_invalid:
        return []
    return Message.objects.match(url)


text:
#region License

#endregion License

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

using Microsoft.Xna.Framework;

using MonoGame.Tests.Components;

#if IPHONE
using MonoTouch.Foundation;
using MonoTouch.UIKit;
#endif

namespace MonoGame.Tests {
	class TestGameBase : Game, IFrameInfoSource {
		private bool _isExiting;

		public TestGameBase ()
		{
            Content.RootDirectory = AppDomain.CurrentDomain.BaseDirectory;
			Services.AddService<IFrameInfoSource> (this);
			SuppressExtraUpdatesAndDraws = true;
		}

		#region IFrameInfoSource Implementation

		private FrameInfo _frameInfo;
		public FrameInfo FrameInfo
		{
			get { return _frameInfo; }
		}

		#endregion IFrameInfoSource Implementation

		public Predicate<FrameInfo> ExitCondition { get; set; }
		public bool SuppressExtraUpdatesAndDraws { get; set; }

		public event EventHandler<FrameInfoEventArgs> InitializeWith;
		public event EventHandler<FrameInfoEventArgs> LoadContentWith;
		public event EventHandler<FrameInfoEventArgs> UnloadContentWith;
		public event EventHandler<FrameInfoEventArgs> DrawWith;
		public event EventHandler<FrameInfoEventArgs> UpdateWith;
		public event EventHandler<FrameInfoEventArgs> UpdateOncePerDrawWith;

		public event EventHandler<FrameInfoEventArgs> PreLoadContentWith;
		public event EventHandler<FrameInfoEventArgs> PreUnloadContentWith;
		public event EventHandler<FrameInfoEventArgs> PreDrawWith;
		public event EventHandler<FrameInfoEventArgs> PreUpdateWith;

		public void ClearActions ()
		{
			InitializeWith = null;
			LoadContentWith = null;
			UnloadContentWith = null;
			DrawWith = null;
			UpdateWith = null;
			UpdateOncePerDrawWith = null;

			PreLoadContentWith = null;
			PreUnloadContentWith = null;
			PreDrawWith = null;
			PreUpdateWith = null;
		}

		private void SafeRaise (EventHandler<FrameInfoEventArgs> handler)
		{
			if (handler != null)
				handler (this, new FrameInfoEventArgs(FrameInfo));
		}

		protected override void Initialize ()
		{
			SafeRaise (InitializeWith);
			base.Initialize ();
		}

		protected override void LoadContent ()
		{
			SafeRaise (PreLoadContentWith);
			base.LoadContent ();
			SafeRaise (LoadContentWith);
		}

		protected override void UnloadContent ()
		{
			SafeRaise (PreUnloadContentWith);
			base.UnloadContent ();
			SafeRaise (UnloadContentWith);
		}

		public new void Run (Predicate<FrameInfo> until = null)
		{
			if (until != null)
				ExitCondition = until;
#if XNA
			try {
				base.Run ();
			} finally {
				// XNA (WinForms) leaves WM_QUIT hanging around
				// in the message queue sometimes, and when it
				// does, all future windows that are created are
				// instantly killed.  So, we manually absorb any
				// WM_QUIT that exists.
				AbsorbQuitMessage ();
			}
#elif IPHONE || ANDROID
			RunOnMainThreadAndWait();
#else
			base.Run (GameRunBehavior.Synchronous);
#endif
		}

#if IPHONE || ANDROID
		private void RunOnMainThreadAndWait()
		{
			var exitEvent = new ManualResetEvent(false);
			var exitHandler = new EventHandler<EventArgs>(
				(sender, e) => exitEvent.Set ());

			Exiting += exitHandler;
			try {
				InvokeRunOnMainThread();
				var maxExecutionTime = TimeSpan.FromSeconds(30);
				if (!exitEvent.WaitOne (maxExecutionTime)) {
					throw new TimeoutException (string.Format (
						"Game.Run timed out.  Maximum execution time is {0}.",
						maxExecutionTime));
				}
			}
			finally {
				Exiting -= exitHandler;
			}
		}
#endif

#if IPHONE
		private void InvokeRunOnMainThread()
		{
			Exception ex = null;
			UIApplication.SharedApplication.InvokeOnMainThread(() => {
				try {
					base.Run (GameRunBehavior.Asynchronous);
				} catch (Exception innerEx) {
					ex = innerEx;
				}
			});

			if (ex != null)
				throw ex;
		}
#endif

#if ANDROID
		private void InvokeRunOnMainThread()
		{
			throw new NotImplementedException(
				"Android need to implement TestGameBase.InvokeRunOnMainThread");
		}
#endif

		private readonly UpdateGuard _updateGuard = new UpdateGuard ();
		protected override void Update (GameTime gameTime)
		{
			_frameInfo.AdvanceUpdate (gameTime);
			EvaluateExitCondition ();

			if (_isExiting && SuppressExtraUpdatesAndDraws)
				return;

			SafeRaise (PreUpdateWith);

			base.Update (gameTime);

			if (_updateGuard.ShouldUpdate (FrameInfo))
				UpdateOncePerDraw (gameTime);

			SafeRaise (UpdateWith);
		}

		protected virtual void UpdateOncePerDraw (GameTime gameTime)
		{
			SafeRaise (UpdateOncePerDrawWith);
		}

		protected override void Draw (GameTime gameTime)
		{
			_frameInfo.AdvanceDraw (gameTime);
			EvaluateExitCondition ();

			if (_isExiting && SuppressExtraUpdatesAndDraws)
				return;

			SafeRaise (PreDrawWith);
			base.Draw (gameTime);
			SafeRaise (DrawWith);
		}

		private void EvaluateExitCondition ()
		{
			if (_isExiting || ExitCondition == null)
				return;

			if (ExitCondition (_frameInfo)) {
				_isExiting = true;
				Exit ();
			}
		}

#if XNA
		[StructLayout (LayoutKind.Sequential)]
		public struct NativeMessage {
			public IntPtr handle;
			public uint msg;
			public IntPtr wParam;
			public IntPtr lParam;
			public uint time;
			public System.Drawing.Point p;
		}

		[DllImport("user32.dll")]
		[return: MarshalAs(UnmanagedType.Bool)]
		private static extern bool PeekMessage(
			out NativeMessage msg, IntPtr hWnd,
			uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);

		[DllImport ("user32.dll")]
		private static extern int GetMessage (
			out NativeMessage msg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax);

		const uint WM_QUIT = 0x12;

		private static void AbsorbQuitMessage ()
		{
			NativeMessage msg;
			if (!PeekMessage (out msg, IntPtr.Zero, 0, 0, 0))
				return;

			do {
				int result = GetMessage (out msg, IntPtr.Zero, 0, 0);
				if (result == -1)
					return;
			} while (msg.msg != WM_QUIT);
		}
#endif
	}
}


text:
(function () {

    var randomStart;

    function randomizeCoffeeCounter()
    {
        writeToSpans(getRandomInt(20000, 24000));
    }

    function writeToSpans(number)
    {
        randomStart = number;
        number = number.toString();
        var wrapper = document.getElementsByClassName('coffee-counter')[0];
        var spans = wrapper.getElementsByTagName('span');

        for (var i = 0, len = number.length; i < len; i++) {
            spans[i].innerHTML = number[i];
        }
    }

    setInterval(updateCoffeeCounter, 4000);

    function updateCoffeeCounter()
    {
        writeToSpans((randomStart + getRandomInt(10, 15)));
    }

    /**
     * Returns a random integer between min (inclusive) and max (inclusive)
     * Using Math.round() will give you a non-uniform distribution!
     */
    function getRandomInt(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    randomizeCoffeeCounter();
})();


text:
//
//  PNPresenceObservationView.m
//  pubnub
//
//  Created by Sergey Mamontov on 3/31/14.
//  Copyright (c) 2014 PubNub Inc. All rights reserved.
//

#import "PNPresenceObservationView.h"
#import "PNObjectInformationDelegate.h"
#import "PNPresenceObservationHelper.h"
#import "PNObjectInformationView.h"
#import "NSString+PNLocalization.h"
#import "NSObject+PNAddition.h"
#import "UIView+PNAddition.h"
#import "PNObjectCell.h"
#import "PNAlertView.h"
#import "PNButton.h"

#pragma mark Static

static NSTimeInterval const kPNViewAppearAnimationDuration = 0.4f;
static NSTimeInterval const kPNViewDisappearAnimationDuration = 0.2f;

#pragma mark - Private interface declaration

@interface PNPresenceObservationView () <PNObjectInformationDelegate, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate>

#pragma mark - Properties

/**
 Stores reference on table which display all channels on which client subscribed at this moment and can be used for
 presence manipulation.
 */
@property (nonatomic, pn_desired_weak) IBOutlet UITableView *channelsList;

/**
 Stores reference on action button which allow to enable or disable presence observation on provided channel.
 */
@property (nonatomic, pn_desired_weak) IBOutlet PNButton *actionButton;

@property (nonatomic, strong) IBOutlet PNPresenceObservationHelper *presenceStateHelper;

/**
 Stores whether view configured to disaply interface for presence enabling or not.
 */
@property (nonatomic, assign, getter = isPresenceEnablingState) BOOL presenceEnablingState;

#pragma mark - Instance methods

- (void)updateLayout;

#pragma mark - Handler methods

- (IBAction)handleChannelAddButtonTap:(id)sender;
- (IBAction)handleChannelGroupAddButtonTap:(id)sender;
- (IBAction)handleActionButtonTap:(id)sender;
- (IBAction)handleCloseButtonTap:(id)sender;

#pragma mark -

@end

#pragma mark - Public interface implementation

@implementation PNPresenceObservationView

#pragma mark - Instance methods

+ (instancetype)viewFromNibForEnabling {

    // Swap method which should provide name for NIB file.
    [self swizzleMethod:@selector(viewNibName) with:@selector(viewNibNameForEnabling)];

    PNPresenceObservationView *view = [self viewFromNib];
    view.presenceEnablingState = YES;

    // Swap method implementation back to restore original.
    [self swizzleMethod:@selector(viewNibName) with:@selector(viewNibNameForEnabling)];

    return view;
}

+ (instancetype)viewFromNibForDisabling {

    // Swap method which should provide name for NIB file.
    [self swizzleMethod:@selector(viewNibName) with:@selector(viewNibNameForDisabling)];

    PNPresenceObservationView *view = [self viewFromNib];

    // Swap method implementation back to restore original.
    [self swizzleMethod:@selector(viewNibName) with:@selector(viewNibNameForDisabling)];

    return view;
}

+ (NSString *)viewNibNameForEnabling {

    return @"PNPresenceObservationEnableView";
}

+ (NSString *)viewNibNameForDisabling {

    return @"PNPresenceObservationDisableView";
}

- (void)awakeFromNib {

    // Forward method call to the super class
    [super awakeFromNib];

    [self updateLayout];
}

- (void)setPresenceEnablingState:(BOOL)presenceEnablingState {

    BOOL isStateChanged = presenceEnablingState != _presenceEnablingState;
    _presenceEnablingState = presenceEnablingState;
    self.presenceStateHelper.enablingPresenceObservation = presenceEnablingState;

    if (isStateChanged) {

        [self updateLayout];
    }
}

- (void)updateLayout {

    self.actionButton.enabled = [self.presenceStateHelper isAbleToChangePresenceState];
}

- (NSTimeInterval)appearAnimationDuration {

    return kPNViewAppearAnimationDuration;
}

- (NSTimeInterval)disappearAnimationDuration {

    return kPNViewDisappearAnimationDuration;
}

#pragma mark - Handler methods

- (IBAction)handleChannelAddButtonTap:(id)sender {

    PNObjectInformationView *information = [PNObjectInformationView viewFromNib];
    information.delegate = self;
    [information showWithOptions:PNViewAnimationOptionTransitionFadeIn animated:YES];
}

- (IBAction)handleChannelGroupAddButtonTap:(id)sender {

    PNObjectInformationView *information = [PNObjectInformationView viewFromNibForChannelGroup];
    information.delegate = self;
    [information showWithOptions:PNViewAnimationOptionTransitionFadeIn animated:YES];
}

- (IBAction)handleActionButtonTap:(id)sender {

    PNAlertView *progressAlertView = [PNAlertView viewForProcessProgress];
    [progressAlertView show];

    __block __pn_desired_weak __typeof(self) weakSelf = self;
    [self.presenceStateHelper performRequestWithBlock:^(NSArray *channels, PNError *presenceManipulationError) {

        [progressAlertView dismissWithAnimation:YES];

        PNAlertType type = (presenceManipulationError ? PNAlertWarning : PNAlertSuccess);
        NSString *shortDescription = nil;
        NSString *detailedDescription = nil;

        if (!presenceManipulationError) {

            [weakSelf.channelsList reloadData];
            [weakSelf updateLayout];

            shortDescription = @"presenceObservationSuccessAlertViewShortDescription";
            NSString *localizedKey = @"presenceObservationEnableSuccessAlertViewDetailedDescription";
            if (!self.isPresenceEnablingState) {

                localizedKey = @"presenceObservationDisableSuccessAlertViewDetailedDescription";
            }

            detailedDescription = [NSString stringWithFormat:[localizedKey localized],
                                   [[channels valueForKey:@"name"] componentsJoinedByString:@", "]];
        }
        else {

            shortDescription = @"presenceObservationFailureAlertViewShortDescription";
            NSString *localizedKey = @"presenceObservationEnableFailureAlertViewDetailedDescription";
            if (!self.isPresenceEnablingState) {

                localizedKey = @"presenceObservationDisableFailureAlertViewDetailedDescription";
            }

            detailedDescription = [NSString stringWithFormat:[localizedKey localized],
                                   [[channels valueForKey:@"name"] componentsJoinedByString:@", "], presenceManipulationError.localizedFailureReason];
        }

        if (detailedDescription) {

            PNAlertView *alert = [PNAlertView viewWithTitle:@"presenceObservationAlertViewTitle" type:type
                                               shortMessage:shortDescription detailedMessage:detailedDescription
                                          cancelButtonTitle:@"confirmButtonTitle" otherButtonTitles:nil andEventHandlingBlock:NULL];
            [alert show];
        }
    }];
}

- (IBAction)handleCloseButtonTap:(id)sender {

    [self dismissWithOptions:PNViewAnimationOptionTransitionFadeOut animated:YES];
}

#pragma mark - Channel information delegate methods

- (void)objectInformation:(PNObjectInformationView *)informationView didEndEditing:(id <PNChannelProtocol>)object
                 withState:(NSDictionary *)channelState andPresenceObservation:(BOOL)shouldObserverPresence {

    [informationView dismissWithOptions:PNViewAnimationOptionTransitionFadeOut animated:YES];

    if (![self.presenceStateHelper willChangePresenceStateForChanne:object]) {

        [self.presenceStateHelper addChannel:object];

        [self.channelsList reloadData];
        [self updateLayout];
    }
}

#pragma mark - UITableVide delegate methods

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return [[self.presenceStateHelper channels] count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *channelCellIdentifier = @"channelCellIdentifier";
    PNObjectCell *cell = (PNObjectCell *)[tableView dequeueReusableCellWithIdentifier:channelCellIdentifier];
    if (!cell) {

        cell = [[PNObjectCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:channelCellIdentifier];
        cell.showBadge = NO;
    }
    PNChannel *channel = [[self.presenceStateHelper channels] objectAtIndex:indexPath.row];
    [cell updateForObject:channel];
    if ([self.presenceStateHelper willChangePresenceStateForChanne:channel]) {

        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }
    else {

        cell.accessoryType = UITableViewCellAccessoryNone;
    }

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    PNObjectCell *cell = (PNObjectCell *)[tableView cellForRowAtIndexPath:indexPath];
    PNChannel *channel = [[self.presenceStateHelper channels] objectAtIndex:indexPath.row];

    if (cell.accessoryType == UITableViewCellAccessoryNone) {

        [self.presenceStateHelper addChannel:channel];
    }
    else {

        [self.presenceStateHelper removeChannel:channel];
    }
    [self.channelsList reloadData];
    [self updateLayout];
}

#pragma mark -

@end


text:
<?php

/**
 * @namespace
 */
namespace Kokoroe\Component\Mapper\Test;

use Kokoroe\Component\Mapper\Mapper;
use PHPUnit_Framework_TestCase;
use DateTime;

class MapperTest extends PHPUnit_Framework_TestCase
{
    /**
     * @expectedException RuntimeException
     * @expectedExceptionMessage The class Kokoroe\Component\Mapper\Test\UserBadSetter does not have a setter for id property.
     */
    public function testHydrateWithBadSetter()
    {
        Mapper::hydrate([
            'id' => 1,
            'name' => 'Axel'
        ], UserBadSetter::class);
    }

    /**
     * @expectedException RuntimeException
     * @expectedExceptionMessage The class ArrayObject does not have add() method.
     */
    public function testHydrateWithBadCollection()
    {
        Mapper::hydrate([
            'id' => 1,
            'name' => 'Axel',
            'articles' => [
                [
                    'title' => 'foo'
                ]
            ]
        ], UserBadCollection::class);
    }

    /**
     * @expectedException RuntimeException
     * @expectedExceptionMessage The method Kokoroe\Component\Mapper\Test\UserBadSetterWithoutParam::setId() does not have a parameter.
     */
    public function testHydrateWithBadSetterWithoutParam()
    {
        Mapper::hydrate([
            'id' => 1,
            'name' => 'Axel'
        ], UserBadSetterWithoutParam::class);
    }

    public function testHydrate()
    {
        $createAt = new DateTime('now');

        $user = Mapper::hydrate([
            'id' => 1,
            'name' => 'Axel',
            'create_at' => $createAt,
            'delete_at' => null,
            'key_not_found' => 'bar',
            'articles' => [
                [
                    'title' => 'test',
                    'content' => 'foo',
                    'author' => [
                        'id' => 1,
                        'name' => 'Axel'
                    ],
                    'tags' => ['test', 'mapping'],
                    'tag' => 'foo'
                ],
                [
                    'title' => 'test 2',
                    'content' => 'foo 2',
                    'author' => [
                        'id' => 1,
                        'name' => 'Axel'
                    ],
                    'tags' => ['test', 'mapping'],
                    'tag' => 'foo'
                ]
            ]
        ], User::class, true);

        $this->assertInstanceOf('Kokoroe\Component\Mapper\Test\User', $user);

        $this->assertEquals(1, $user->getId());
        $this->assertInstanceOf('DateTime', $user->getCreateAt());
        $this->assertEquals($createAt, $user->getCreateAt());
    }
}


text:
target=juser@negk

scp planet.xml default.xml $target:/tmp/
ssh $target -t \
    sudo mv /tmp/planet.xml /usr/local/etc/flumotion/managers/default/
ssh $target -t \
    sudo mv /tmp/default.xml /usr/local/etc/flumotion/workers/


text:
payment-cdi-event: Use CDI Events to Process Debit and Credit Operations
========================================================================
Author: Elvadas Nono
Level: Beginner
Technologies: CDI
Summary: Demonstrates how to use CDI 1.0 Events
Target Product: EAP
Product Versions: EAP 6.1, EAP 6.2
Source: <https://github.com/jboss-developer/jboss-eap-quickstarts/>

What is it?
-----------

This quickstart demonstrates how to use *CDI 1.0 Events* in  Red Hat JBoss Enterprise Application Platform.

The JSF front-end client allows you to create both credit and debit operation events.

To test this quickstart, enter an amount, choose either a Credit or Debit operation, and then click on *Pay* to create the event.

A Session scoped (@SessionScoped) payment event handler catches the operation and produces (@Produces) a named list of all operations performed during this session.  The event is logged in the JBoss console and the event list is displayed in a table at the bottom of the form.

The payment-cdi-event quickstart defines the following classes:

 *   PaymentBean:
     *   A session scoped bean that stores the payment form information:
         *   payment amount
         *   operation type: debit or credit
     *   It contains the following utilities methods:
         *   public String pay(): Process the operation when the user clicks on submit. We have only one JSP page, so the method does not return anything and the flow of control doesn't change.
         *   public void reset(): Clear the payment form data.
 *   PaymentEvent: We have only one Event. It handles both credit and debit operations. Qualifiers help us to make the difference at injection point.
 *   PaymentTypeEnum:  A typesafe enum is used to represent the operation payment type. It contains utility methods to convert between String and Enum.
 *   The qualifiers package contains the Credit and Debit classes. The annotation determines the operation of injecting Event.
 *   The handler package containss Interfaces and implementations of PaymentEvent Observers.
     *   ICreditEventObserver: Interface to listen to CREDIT Event Only (@Observes @Credit).
     *   IDebitEventObserver: Interface to listen to DEBIT Event (@Observes @Debit).
 *   PaymentHandler:
     *   The concrete implementation of the payment handler, it implements both IcreditEventObserver and IDebitEventObserver.
     *   The payment handler exposes the list of events caught during a session ( @Named  name=payments).

System requirements
-------------------

The application this project produces is designed to be run on Red Hat JBoss Enterprise Application Platform 6.1 or later.

All you need to build this project is Java 6.0 (Java SDK 1.6) or later, Maven 3.0 or later.

Configure Maven
---------------

If you have not yet done so, you must [Configure Maven](../README.md#configure-maven) before testing the quickstarts.

Start the JBoss Server
-------------------------

1. Open a command line and navigate to the root of the JBoss server directory.
2. The following shows the command line to start the server:

        For Linux:   JBOSS_HOME/bin/standalone.sh
        For Windows: JBOSS_HOME\bin\standalone.bat

Build and Deploy the Quickstart
-------------------------

_NOTE: The following build command assumes you have configured your Maven user settings. If you have not, you must include Maven setting arguments on the command line. See [Build and Deploy the Quickstarts](../README.md#build-and-deploy-the-quickstarts) for complete instructions and additional options._

1. Make sure you have started the JBoss Server as described above.
2. Open a command line and navigate to the root directory of this quickstart.
3. Type this command to build and deploy the archive:

        mvn clean install jboss-as:deploy

4. This will deploy `target/jboss-payment-cdi-event.war` to the running instance of the server.

Access the application
---------------------

The application will be running at the following URL: <http://localhost:8080/jboss-payment-cdi-event/>.

Undeploy the Archive
--------------------

1. Make sure you have started the JBoss Server as described above.
2. Open a command line and navigate to the root directory of this quickstart.
3. When you are finished testing, type this command to undeploy the archive:

        mvn jboss-as:undeploy

Run the Quickstart in JBoss Developer Studio or Eclipse
-------------------------------------
You can also start the server and deploy the quickstarts from Eclipse using JBoss tools. For more information, see [Use JBoss Developer Studio or Eclipse to Run the Quickstarts](../README.md#use-jboss-developer-studio-or-eclipse-to-run-the-quickstarts)

Debug the Application
------------------------------------

If you want to debug the source code or look at the Javadocs of any library in the project, run either of the following commands to pull them into your local repository. The IDE should then detect them.

        mvn dependency:sources
        mvn dependency:resolve -Dclassifier=javadoc


text:
import { Routes } from '@angular/router';
import { HomeComponent } from './home';
import { AboutComponent } from './about';
import { NoContentComponent } from './no-content';

import { AuthService } from './services';
import { RouterModule } from '@angular/router';
import { ModuleWithProviders } from '@angular/core'
import { Main, Notes, About, Login, Register, Home, Contact } from './containers';

import { DataResolver } from './app.resolver';

export const ROUTES: Routes = [
  // { path: '',      component: HomeComponent },
  // { path: 'home',  component: HomeComponent },
  // { path: 'about', component: AboutComponent },
  // { path: 'detail', loadChildren: './+detail#DetailModule'},
  // { path: 'barrel', loadChildren: './+barrel#BarrelModule'},
  // { path: '**',    component: NoContentComponent },
  {
    path: '',
    //component: Main,
    //canActivate: [AuthService],
    children: [
      { path: '', component: Home },
      //{ path: 'about', component: About }
    ]
  },
  { path: 'login', component: Login },
  { path: 'register', component: Register },
  { path: 'home', component: Home },
  { path: 'about', component: About },
  { path: 'contact', component: Contact },
  { path: '**', redirectTo: '' },
];

// export const routes: ModuleWithProviders = RouterModule.forRoot([
//   {
//     path: '',
//     //component: Main,
//     canActivate: [AuthService],
//     children: [
//       { path: '', component: Notes },
//       //{ path: 'about', component: About }
//     ]
//   },
//   { path: 'login', component: Login },
//   { path: 'register', component: Register },
//   { path: 'home', component: Home },
//   { path: 'about', component: About },
//   { path: '**', redirectTo: '' },
// ]);


text:
package com.facebook.buck.rules.coercer;

import com.facebook.buck.io.ProjectFilesystem;
import com.facebook.buck.rules.CellPathResolver;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;

import java.nio.file.Path;

public class OptionalTypeCoercer<T> extends LeafTypeCoercer<Optional<T>> {

  private final TypeCoercer<T> coercer;

  public OptionalTypeCoercer(TypeCoercer<T> coercer) {
    Preconditions.checkArgument(
        !coercer.getOutputClass().isAssignableFrom(Optional.class),
        "Nested optional fields are ambiguous.");
    this.coercer = coercer;
  }

  @Override
  @SuppressWarnings("unchecked")
  public Class<Optional<T>> getOutputClass() {
    return (Class<Optional<T>>) (Class<?>) Optional.class;
  }

  @Override
  public Optional<T> coerce(
      CellPathResolver cellRoots,
      ProjectFilesystem filesystem,
      Path pathRelativeToProjectRoot,
      Object object)
      throws CoerceFailedException {
    if (object == null) {
      return Optional.absent();
    }
    return Optional.of(coercer.coerce(cellRoots, filesystem, pathRelativeToProjectRoot, object));
  }

}


text:
import { Injectable } from '@nestjs/common';
import { CommentDocument, Comment } from '../../models/comment.model';
import { Category, CategoryDocument } from '../../models/category.model';
import { Article, ArticleDocument } from '../../models/article.model';
import { Model } from 'mongoose';
import os from 'os';
import { InjectModel } from '@nestjs/mongoose';

@Injectable()
export class DashboardService {
    constructor(
        @InjectModel(Article.name) private readonly articleModel: Model<ArticleDocument>,
        @InjectModel(Comment.name) private readonly commentModel: Model<CommentDocument>,
        @InjectModel(Category.name) private readonly categoryModel: Model<CategoryDocument>
    ) {}

    async getStatisticalInfo() {
        const [articleCount, categoryCount, commentCount] = await Promise.all([
            this.articleModel.countDocuments({}),
            this.categoryModel.countDocuments({}),
            this.commentModel.countDocuments({}),
        ]);
        return {
            articleCount,
            categoryCount,
            commentCount,
        };
    }

    getSystemInfo() {
        const arch = os.arch();
        const cpus = os.cpus();
        const freemem = os.freemem();
        const type = os.type();
        const hostname = os.hostname();
        const release = os.release();
        const totalmem = os.totalmem();
        return {
            arch,
            cpus,
            type,
            freemem,
            totalmem,
            release,
            hostname,
        };
    }
}


text:
using System;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
namespace SOURCE.Domaine
{
    public partial class Grade
    {
        [DataMember]
        public long ID { get; set; }
        [DataMember]
        [StringLength(2000)]
        public string Code { get; set; }
        [DataMember]
        [StringLength(2000)]
        public string CodeEchange { get; set; }
        [DataMember]
        [StringLength(2000)]
        public string Description { get; set; }
        [DataMember]
        public bool Archive { get; set; }
    }
}


text:
class WebDevToolsClientDelegate;
class WebView;

// WebDevToolsClient represents DevTools client sitting in the Glue. It provides
// direct and delegate Apis to the host.
class WebDevToolsClient {
 public:
  static WebDevToolsClient* Create(
      WebView* view,
      WebDevToolsClientDelegate* delegate);

  WebDevToolsClient() {}
  virtual ~WebDevToolsClient() {}

  virtual void DispatchMessageFromAgent(const std::string& class_name,
                                        const std::string& method_name,
                                        const std::string& raw_msg) = 0;

 private:
  DISALLOW_COPY_AND_ASSIGN(WebDevToolsClient);
};

#endif  // WEBKIT_GLUE_WEBDEVTOOLSCLIENT_H_


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="viewport" content="width=device-width"/>

                [[Text]]


text:
package be.klak.junit.jasmine.classes;

import be.klak.junit.jasmine.JasmineSuite;

@JasmineSuite(specs = { "crashingJSCode.js" })
public class JasmineTestRunnerExceptionInJSCode {

}


text:
import sys
from Kamaelia.Util.Backplane import *
from Kamaelia.Util.Console import *
from Kamaelia.Chassis.Pipeline import Pipeline
from Kamaelia.Visualisation.PhysicsGraph.TopologyViewer import TopologyViewer
from Kamaelia.Visualisation.PhysicsGraph.lines_to_tokenlists import lines_to_tokenlists
from Kamaelia.File.ReadFileAdaptor import ReadFileAdaptor
from Kamaelia.Visualisation.ER.ERVisualiserServer import ERVisualiser
from Kamaelia.Experimental.ERParsing import ERParser,ERModel2Visualiser

Backplane("TOPOLOGY").activate()

Pipeline(
    ConsoleReader(">>> "),
    PublishTo("TOPOLOGY"),
).activate()

if len(sys.argv)> 1:
    Pipeline(
        ReadFileAdaptor(sys.argv[1]),
        ERParser(),
        ERModel2Visualiser(),
        PublishTo("TOPOLOGY"),
    ).activate()

Pipeline(
    SubscribeTo("TOPOLOGY"),
    lines_to_tokenlists(),
    ERVisualiser(screensize = (1024,768), fullscreen = True),
    ConsoleEchoer(),

).run()


text:
def longest_string(list_of_words)
  # Your code goes here!
return list_of_words.min { |x,y| y.length <=> x.length }
end

my_array=["abcd", "adfdfdf","p", "hi", "bye", "hello"]
longest_string(my_array)


text:
/**
 * @file
 * This file is to keep design in sync with other platforms.  Right now
 * there is no api for network monitoring in arduino.
 */

#include "caipinterface.h"

#include <Arduino.h>
#include <Ethernet.h>
#include <socket.h>
#include <w5100.h>
#include <EthernetUdp.h>
#include <IPAddress.h>

#include "logger.h"
#include "cacommon.h"
#include "caipadapter.h"
#include "caadapterutils.h"
#include "oic_malloc.h"
#include "oic_string.h"

#define TAG "IPNW"

// Since the CA abstraction expects a value for "family", AF_INET will be
// defined & used (as-is defined in the linux socket headers).
#define AF_INET (2)

CAResult_t CAIPStartNetworkMonitor()
{
    return CA_STATUS_OK;
}

CAResult_t CAIPStopNetworkMonitor()
{
    return CA_STATUS_OK;
}

/// Retrieves the IP address assigned to Arduino Ethernet shield
void CAArduinoGetInterfaceAddress(uint32_t *address)
{
    OIC_LOG(DEBUG, TAG, "IN");
    VERIFY_NON_NULL_VOID(address, TAG, "address");

    //TODO : Fix this for scenarios when this API is invoked when device is not connected
    uint8_t rawIPAddr[4];
    W5100.getIPAddress(rawIPAddr);
    *address = (uint32_t) rawIPAddr;

    OIC_LOG_V(DEBUG, TAG, "address:%d.%d.%d.%d", rawIPAddr[0], rawIPAddr[1],
              rawIPAddr[2], rawIPAddr[3]);
    OIC_LOG(DEBUG, TAG, "OUT");
    return;
}

u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
{
    bool result = true;

    u_arraylist_t *iflist = u_arraylist_create();
    if (!iflist)
    {
        OIC_LOG(ERROR, TAG, "Failed to create iflist");
        return NULL;
    }

    CAInterface_t *ifitem = (CAInterface_t *)OICCalloc(1, sizeof(CAInterface_t));
    if (!ifitem)
    {
        OIC_LOG(ERROR, TAG, "Malloc failed");
        goto exit;
    }

    // Since Arduino currently only supports one interface, the next 4 lines are sufficient.
    OICStrcpy(ifitem->name, INTERFACE_NAME_MAX, "ETH");
    ifitem->index = 1;
    ifitem->family = AF_INET;
    ifitem->flags = 0;
    CAArduinoGetInterfaceAddress(&ifitem->ipv4addr);

    result = u_arraylist_add(iflist, ifitem);
    if (!result)
    {
        OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
        goto exit;
    }

    OIC_LOG_V(DEBUG, TAG, "Added interface: %s (%d)", ifitem->name, ifitem->family);

    return iflist;

exit:
    u_arraylist_destroy(iflist);
    return NULL;
}


text:
<?php

namespace yii\validators;

/**
 * DefaultValueValidator sets the attribute to be the specified default value.
 *
 * DefaultValueValidator is not really a validator. It is provided mainly to allow
 * specifying attribute default values when they are empty.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
class DefaultValueValidator extends Validator
{
    /**
     * @var mixed the default value or an anonymous function that returns the default value which will
     * be assigned to the attributes being validated if they are empty. The signature of the anonymous function
     * should be as follows,
     *
     * ```php
     * function foo($model, $attribute) {
     *     // compute value
     *     return $value;
     * }
     * ```
     */
    public $value;
    /**
     * @var boolean this property is overwritten to be false so that this validator will
     * be applied when the value being validated is empty.
     */
    public $skipOnEmpty = false;

    /**
     * @inheritdoc
     */
    public function validateAttribute($model, $attribute)
    {
        if ($this->isEmpty($model->$attribute)) {
            if ($this->value instanceof \Closure) {
                $model->$attribute = call_user_func($this->value, $model, $attribute);
            } else {
                $model->$attribute = $this->value;
            }
        }
    }
}


text:
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**repositories** | [**\OpenAPI\Client\Model\Link**](Link.md) |  | [optional]
**self** | [**\OpenAPI\Client\Model\Link**](Link.md) |  | [optional]
**_class** | **string** |  | [optional]

[[Back to Model list]](../../README.md#models) [[Back to API list]](../../README.md#endpoints) [[Back to README]](../../README.md)


text:
SYNONYM

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
Encycl. 3:200. 1789

#### Original name
null

### Remarks
null


text:
<!DOCTYPE html>
<html>
<head>
    <script src="bower_components/threejs/build/three.js"></script>
    <script src="bower_components/underscore/underscore.js"></script>
    <script src="bower_components/jquery/dist/jquery.js"></script>

    <script src="lib/shaders/ConvolutionShader.js"></script>
    <script src="lib/shaders/CopyShader.js"></script>
    <script src="lib/shaders/FXAAShader.js"></script>
    <script src="lib/shaders/VignetteShader.js"></script>

    <script src="lib/postprocessing/EffectComposer.js"></script>
    <script src="lib/postprocessing/MaskPass.js"></script>
    <script src="lib/postprocessing/RenderPass.js"></script>
    <script src="lib/postprocessing/ShaderPass.js"></script>
    <script src="lib/postprocessing/BloomPass.js"></script>

    <script data-main="src/main.js" src="bower_components/requirejs/require.js"></script>

    <title>.::' INSuRANcE '::.</title>

    <style>
        body, html {
            background: black;
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
        canvas {
            margin: 0;
            padding: 0;
        }
    </style>
</head>
<body>
</body>
</html>


text:
/**
 * Licensed under Apache License v2. See LICENSE for more information.
 */
package org.inaetics.remote;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * @author Amdatu Project Team
 */
public final class HashUtil {

    /** The message digest algorithm used to fingerprint files. */
    private static final String DIGEST_ALG = "MD5";

    /** The hexadecimal alphabet. */
    private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();

    /**
     * Creates a new message digest instance.
     *
     * @return a new {@link MessageDigest} instance, never null.
     * @throws RuntimeException in case the desired message digest algorithm is not
     *         supported by the platform.
     */
    public static MessageDigest createDigester() {
        try {
            return MessageDigest.getInstance(DIGEST_ALG);
        }
        catch (NoSuchAlgorithmException exception) {
            throw new RuntimeException("No such algorithm: " + DIGEST_ALG);
        }
    }

    /**
     * Creates a hexadecimal representation of all given bytes an concatenates these
     * hex-values to a single string.
     *
     * @param bytes the byte values to convert, cannot be null.
     * @return a hex-string of the given bytes, never null.
     */
    public static String toHexString(byte[] bytes) {
        // based on <http://stackoverflow.com/a/9855338/229140>
        char[] hexChars = new char[bytes.length * 2];
        int v;
        for (int j = 0; j < bytes.length; j++) {
            v = bytes[j] & 0xFF;
            hexChars[j * 2] = HEX_DIGITS[v >>> 4];
            hexChars[j * 2 + 1] = HEX_DIGITS[v & 0x0F];
        }
        return new String(hexChars);
    }

    public static String hash(String msg) {
        try {
            return toHexString(createDigester().digest(msg.getBytes("UTF-8")));
        }
        catch (UnsupportedEncodingException e) {
            throw new RuntimeException("UTF-8 not supported?!");
        }
    }

    public static String hash(Method m) {
        return hash(m.toGenericString());
    }
}


text:
import Ember from 'ember';

export default Ember.Route.extend({
  model: function (params) {
    return this.store.find('ingredient', params).then(function(results){
      return results.content;
    });
  }
});


text:
using System.IO;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using XRoadLib.Extensions;
using XRoadLib.Schema;
using XRoadLib.Serialization.Template;

namespace XRoadLib.Serialization.Mapping
{
    public class ContentTypeMap : TypeMap, IContentTypeMap
    {
        private readonly XName _encodedTypeName;
        private readonly ITypeMap _optimizedContentTypeMap;

        public ContentTypeMap(TypeDefinition typeDefinition)
            : base(typeDefinition)
        {
            _encodedTypeName = XName.Get(Definition.Name.LocalName, NamespaceConstants.SoapEnc);
            _optimizedContentTypeMap = new OptimizedContentTypeMap(this);
        }

        public ITypeMap GetOptimizedContentTypeMap()
        {
            return _optimizedContentTypeMap;
        }

        public override async Task<object> DeserializeAsync(XmlReader reader, IXmlTemplateNode templateNode, ContentDefinition content, XRoadMessage message)
        {
            var contentId = reader.GetAttribute("href");

            if (string.IsNullOrWhiteSpace(contentId))
            {
                if (message.IsMultipartContainer)
                    throw new InvalidQueryException("Missing `href` attribute to multipart content.");

                var tempAttachment = new XRoadAttachment(new MemoryStream()) { IsMultipartContent = false };
                message.AllAttachments.Add(tempAttachment);

                if (reader.IsEmptyElement)
                    return await reader.MoveNextAndReturnAsync(tempAttachment.ContentStream).ConfigureAwait(false);

                await reader.ReadAsync().ConfigureAwait(false);

                const int bufferSize = 1000;

                int bytesRead;
                var buffer = new byte[bufferSize];

                while ((bytesRead = await reader.ReadContentAsBase64Async(buffer, 0, bufferSize).ConfigureAwait(false)) > 0)
                    await tempAttachment.ContentStream.WriteAsync(buffer, 0, bytesRead).ConfigureAwait(false);

                return tempAttachment.ContentStream;
            }

            var attachment = message.GetAttachment(contentId.Substring(4));
            if (attachment == null)
                throw new InvalidQueryException($"MIME multipart message does not contain message part with ID `{contentId}`.");

            if (reader.IsEmptyElement)
                return await reader.MoveNextAndReturnAsync(attachment.ContentStream).ConfigureAwait(false);

            await reader.ReadToEndElementAsync().ConfigureAwait(false);

            return attachment.ContentStream;
        }

        public override async Task SerializeAsync(XmlWriter writer, IXmlTemplateNode templateNode, object value, ContentDefinition content, XRoadMessage message)
        {
            var attachment = new XRoadAttachment((Stream)value);
            message.AllAttachments.Add(attachment);

            if (message.BinaryMode == BinaryMode.Attachment)
            {
                if (!(content.Particle is RequestDefinition))
                    await message.Style.WriteExplicitTypeAsync(writer, _encodedTypeName).ConfigureAwait(false);

                await writer.WriteAttributeStringAsync(null, "href", null, $"cid:{attachment.ContentId}").ConfigureAwait(false);
                return;
            }

            await message.Style.WriteTypeAsync(writer, Definition, content).ConfigureAwait(false);

            attachment.IsMultipartContent = false;

            await attachment.WriteAsBase64Async(writer).ConfigureAwait(false);
        }
    }
}