text:
package com.thaiopensource.validate.nvdl;

import com.thaiopensource.util.Localizer;
import com.thaiopensource.util.PropertyId;
import com.thaiopensource.util.PropertyMap;
import com.thaiopensource.util.PropertyMapBuilder;
import com.thaiopensource.util.Uri;
import com.thaiopensource.validate.AbstractSchema;
import com.thaiopensource.validate.IncorrectSchemaException;
import com.thaiopensource.validate.Option;
import com.thaiopensource.validate.OptionArgumentException;
import com.thaiopensource.validate.OptionArgumentPresenceException;
import com.thaiopensource.validate.ResolverFactory;
import com.thaiopensource.validate.Schema;
import com.thaiopensource.validate.ValidateProperty;
import com.thaiopensource.validate.Validator;
import com.thaiopensource.validate.auto.SchemaFuture;
import com.thaiopensource.validate.prop.wrap.WrapProperty;
import com.thaiopensource.xml.sax.CountingErrorHandler;
import com.thaiopensource.xml.sax.DelegatingContentHandler;
import com.thaiopensource.xml.sax.Resolver;
import com.thaiopensource.xml.sax.XmlBaseHandler;
import com.thaiopensource.xml.util.WellKnownNamespaces;
import org.xml.sax.Attributes;
import org.xml.sax.ErrorHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.LocatorImpl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.Vector;

/**
 * Schema implementation for NVDL scripts.
 */
class SchemaImpl extends AbstractSchema {
  /**
   * Mode name used when the script does not define modes and just enters
   * namespace and anyNamespace mappings directly inside rules.
   */
  static private final String IMPLICIT_MODE_NAME = "#implicit";

  /**
   * Mode name used when we have to use this script as an attributes schema.
   * The wrapper mode allows elements from any namespace.
   */
  static private final String WRAPPER_MODE_NAME = "#wrapper";

  /**
   * The NVDL URI.
   */
  static final String NVDL_URI = "http://purl.oclc.org/dsdl/nvdl/ns/structure/1.0";

  /**
   * A hash with the modes.
   */
  private final Hashtable modeMap = new Hashtable();

  /**
   * A hash with the triggers on namespace.
   * Element names are stored concatenated in a string, each name preceded by #.
   */
  private final List triggers = new ArrayList();

  /**
   * The start mode.
   */
  private Mode startMode;

  /**
   * Default base mode, rejects everything.
   */
  private final Mode defaultBaseMode;

  /**
   * Flag indicating if the schema needs to be changed to handle
   * attributes only, the element in this case is a placeholder.
   */
  private final boolean attributesSchema;

  /**
   * Wrapps an IOException as a RuntimeException.
   *
   */
  static private final class WrappedIOException extends RuntimeException {
    /**
     * The actual IO Exception.
     */
    private final IOException exception;

    /**
     * Creates a wrapped exception.
     * @param exception The IOException.
     */
    private WrappedIOException(IOException exception) {
      this.exception = exception;
    }

    /**
     * Get the actual IO Exception.
     * @return IOException.
     */
    private IOException getException() {
      return exception;
    }
  }

  /**
   * Stores information about options that must be supported by the
   * validator.
   */
  static private class MustSupportOption {
    /**
     * The option name.
     */
    private final String name;
    /**
     * The property id.
     */
    private final PropertyId pid;

    /**
     * Locator pointing to where this option is declared.
     */
    private final Locator locator;

    /**
     * Creates a must support option.
     * @param name The option name
     * @param pid property id.
     * @param locator locator pointing to where this option is declared.
     */
    MustSupportOption(String name, PropertyId pid, Locator locator) {
      this.name = name;
      this.pid = pid;
      this.locator = locator;
    }
  }

  /**
   * This class is registered as content handler on the XMLReader that
   * parses the NVDL script.
   * It creates the Schema representation for this script and also validates
   * the script against the NVDL schema.
   */
  private class Handler extends DelegatingContentHandler implements SchemaFuture {
    /**
     * The schema receiver. Used to cretae other schemas and access options.
     */
    private final SchemaReceiverImpl sr;

    /**
     * Flag indicating that we encountered an error.
     */
    private boolean hadError = false;

    /**
     * The error handler.
     */
    private final ErrorHandler eh;

    /**
     * A counting error handler that wraps the error handler.
     * It is useful to stop early if we encounter errors.
     */
    private final CountingErrorHandler ceh;

    /**
     * The Resolver to use for resolving URIs and entities.
     */
    private final Resolver resolver;

    /**
     * Convert error keys to messages.
     */
    private final Localizer localizer = new Localizer(SchemaImpl.class);

    /**
     * Error locator.
     */
    private Locator locator;

    /**
     * Handle xml:base attributes.
     */
    private final XmlBaseHandler xmlBaseHandler = new XmlBaseHandler();

    /**
     * For ignoring foreign elements.
     */
    private int foreignDepth = 0;

    /**
     * The value of rules/@schemaType
     */
    private String defaultSchemaType;

    /**
     * The validator that checks the script against the
     * NVDL RelaxNG schema.
     */
    private Validator validator;

    /**
     * Stores mode data.
     * We use this to handle included and nested modes.
     */
    class ModeData {
      /**
       * Points to the current mode.
       */
      private Mode currentMode = null;

      /**
       * The value of the match attribute on the current rule.
       */
      private ElementsOrAttributes match;

      /**
       * The current element actions.
       */
      private ActionSet actions;

      /**
       * The current attribute actions.
       */
      private AttributeActionSet attributeActions;

      /**
       * The URI reference for the schema for the current validate action.
       * This is as specified in the attribute before any resolution.
       */
      private String schemaUriRef;

      /**
       * The base URI to be used for resolving schemaUriRef.
       */
      private String schemaUriBase;

      /**
       * The current validate action schema type.
       */
      private String schemaType;

      /**
       * The options defined for a validate action.
       */
      private PropertyMapBuilder options;

      /**
       * The options that must be supported by the validator
       * for the current validate action.
       */
      private final Vector mustSupportOptions = new Vector();

      /**
       * The current mode usage, for the current action.
       */
      private ModeUsage modeUsage;

      /**
       * Flag indicating if we are in a namespace rule or in an anyNamespace rule.
       */
      private boolean anyNamespace;

      /**
       * The lastMode stores the last created mode.
       * For example when we have an action we need to create the
       * ModeUsage for it and lastMode points to the mode for that action.
       * It is possible that lastMode is created without having encountered
       * its definition, in the case of nested modes. In that case we have
       * no useMode attribute but a mode element can appear further inside
       * the action (a nested mode). If no mode appears inside the action then
       * we need to resolve the anonymous mode that is not defined to the current mode.
       */
      private Mode lastMode;
    }

    /**
     * Stores mode data.
     */
    ModeData md = new ModeData();

    /**
     * Keeps the mode data stack.
     */
    private Stack modeDataStack = new Stack();

    /**
     * Keeps the elements from NVDL representing the current context.
     * We need it to distinguish between modes, included modes and
     * nested modes.
     */
    private Stack nvdlStack = new Stack();

    /**
     * Creates a handler.
     * @param sr The Schema Receiver implementation for NVDL schemas.
     */
    Handler(SchemaReceiverImpl sr) {
      this.sr = sr;
      this.eh = ValidateProperty.ERROR_HANDLER.get(sr.getProperties());
      this.ceh = new CountingErrorHandler(this.eh);
      this.resolver = ResolverFactory.createResolver(sr.getProperties());
    }

    /**
     * Callback with the document locator.
     * @param locator The document locator.
     */
    public void setDocumentLocator(Locator locator) {
      xmlBaseHandler.setLocator(locator);
      this.locator = locator;
    }

    /**
     * On start document.
     */
    public void startDocument() throws SAXException {
      // creates a validator that validates against the schema for NVDL.
      try {
        PropertyMapBuilder builder = new PropertyMapBuilder(sr.getProperties());
        ValidateProperty.ERROR_HANDLER.put(builder, ceh);
        validator = sr.getNvdlSchema().createValidator(builder.toPropertyMap());
      }
      catch (IOException e) {
        throw new WrappedIOException(e);
      }
      catch (IncorrectSchemaException e) {
        throw new RuntimeException("internal error in RNG schema for NVDL");
      }
      // set that validator content handler as delegate to receive the NVDL schema content.
      setDelegate(validator.getContentHandler());
      // forward the setDocumentLocator and startDocument to the delegate handler.
      if (locator != null)
        super.setDocumentLocator(locator);
      super.startDocument();
    }

    public Schema getSchema() throws IncorrectSchemaException, SAXException {
      if (validator == null || ceh.getHadErrorOrFatalError())
        throw new IncorrectSchemaException();
      Hashset openModes = new Hashset();
      Hashset checkedModes = new Hashset();
      for (Enumeration e = modeMap.keys(); e.hasMoreElements();) {
        String modeName = (String)e.nextElement();
        Mode mode = (Mode)modeMap.get(modeName);
        if (!mode.isDefined())
          error("undefined_mode", modeName, mode.getWhereUsed());
        for (Mode tem = mode; tem != null; tem = tem.getBaseMode()) {
          if (checkedModes.contains(tem))
            break;
          if (openModes.contains(tem)) {
            error("mode_cycle", tem.getName(), tem.getWhereDefined());
            break;
          }
          openModes.add(tem);
        }
        checkedModes.addAll(openModes);
        openModes.clear();
      }
      if (hadError)
        throw new IncorrectSchemaException();
      return SchemaImpl.this;
    }

    public RuntimeException unwrapException(RuntimeException e) throws SAXException, IOException, IncorrectSchemaException {
      if (e instanceof WrappedIOException)
        throw ((WrappedIOException)e).getException();
      return e;
    }

    /**
     * Start element callback.
     * @param uri The namespace uri for this element.
     * @param localName The element local name.
     * @param qName The element qualified name.
     * @param attributes The attributes of this element.
     */
    public void startElement(String uri, String localName,
                             String qName, Attributes attributes)
            throws SAXException {
      // call delegate handler
      super.startElement(uri, localName, qName, attributes);
      // handle xml:base
      xmlBaseHandler.startElement();
      String xmlBase = attributes.getValue(WellKnownNamespaces.XML, "base");
      if (xmlBase != null)
        xmlBaseHandler.xmlBaseAttribute(xmlBase);
      // ignore foreign elements
      if (!NVDL_URI.equals(uri) || foreignDepth > 0) {
        foreignDepth++;
        return;
      }
      // stop if we got errors.
      if (ceh.getHadErrorOrFatalError())
        return;
      // dispatch based on the element name
      if (localName.equals("rules"))
        parseRules(attributes);
      else if (localName.equals("mode")) {
      	String parent = (String)nvdlStack.peek();
        if ("rules".equals(parent))
          parseMode(attributes);
        else if ("mode".equals(parent))
          // mode inside mode - included mode.
          parseIncludedMode(attributes);
        else
          // nested mode
          parseNestedMode(attributes);
      }
      else if (localName.equals("namespace"))
        parseNamespace(attributes);
      else if (localName.equals("anyNamespace"))
        parseAnyNamespace(attributes);
      else if (localName.equals("validate"))
        parseValidate(attributes);
      else if (localName.equals("reject"))
        parseReject(attributes);
      else if (localName.equals("attach"))
        parseAttach(attributes);
      else if (localName.equals("unwrap"))
        parseUnwrap(attributes);
      else if (localName.equals("attachPlaceholder"))
        parseAttachPlaceholder(attributes);
      else if (localName.equals("allow"))
        parseAllow(attributes);
      else if (localName.equals("context"))
        parseContext(attributes);
      else if (localName.equals("option"))
        parseOption(attributes);
      else if (localName.equals("trigger"))
        parseTrigger(attributes);
      else if (localName.equals("schema"))
        error("embedded_schemas");
      else if (localName.equals("cancelNestedActions"))
        parseCancelNestedActions(attributes);
      else if (localName.equals("message"))
    	;  // noop
      else
        throw new RuntimeException("unexpected element \"" + localName + "\"");
      // add the NVDL element on the stack
      nvdlStack.push(localName);

    }

    /**
     * End element callback.
     * @param namespaceURI The namespace uri for this element.
     * @param localName The element local name.
     * @param qName The element qualified name.
     */
    public void endElement(String namespaceURI, String localName,
                           String qName)
            throws SAXException {
      // call the delegate handler
      super.endElement(namespaceURI, localName, qName);
      // handle xml:base
      xmlBaseHandler.endElement();
      // ignore foreign elements
      if (foreignDepth > 0) {
        foreignDepth--;
        return;
      }
      // exit early if we got errors.
      if (ceh.getHadErrorOrFatalError())
        return;
      // pop the NVDL element from the stack
      nvdlStack.pop();
      // dispatch based on element name.
      if (localName.equals("validate"))
        finishValidate();
      else if (localName.equals("mode")) {
        String parent = (String)nvdlStack.peek();
        if ("rules".equals(parent))
          finishMode();
        else if ("mode".equals(parent))
          // mode inside mode - included mode.
          finishIncludedMode();
        else
          // nested mode.
          finishNestedMode();
      }
    }

    /**
     * Parse the rules element.
     * Initializes
     *  the start mode
     *  the current mode
     *  the defaultSchemaType
     * @param attributes The rule element attributes.
     */
    private void parseRules(Attributes attributes) {
      startMode = getModeAttribute(attributes, "startMode");
      // If not start mode specified we create an implicit mode.
      if (startMode == null) {
        startMode = lookupCreateMode(IMPLICIT_MODE_NAME);
        md.currentMode = startMode;
        // mark this implicit mode as not defined in the schema.
        startMode.noteDefined(null);
      }
      // Set the current location as the location the start mode is first used.
      startMode.noteUsed(locator);
      // if the schema should be used for validating only attributes
      // we need to create a wrapper that allows any element from any namespace
      // as the placeholder for the attributes we want to validate.
      if (attributesSchema) {
        Mode wrapper = lookupCreateMode(WRAPPER_MODE_NAME);
        // creates element actions - allow and set them for any namespace
        // the attributes will be validated further in the real schema start mode.
        ActionSet actions = new ActionSet();
        actions.addNoResultAction(new AllowAction(new ModeUsage(startMode, startMode)));
        wrapper.bindElement(NamespaceSpecification.ANY_NAMESPACE, NamespaceSpecification.DEFAULT_WILDCARD, actions);
        wrapper.noteDefined(null);
        // we use the wrapper mode as the start mode.
        startMode = wrapper;
      }
      // Get the default value for schema type if it is specified in rule/@schemaType.
      defaultSchemaType = getSchemaType(attributes);
    }

    /**
     * Parse a mode element.
     * @param attributes The element attributes.
     * @throws SAXException
     */
    private void parseMode(Attributes attributes) throws SAXException {
      // Get the mode (create it if it does not exists) corresponding to the name attribute.
      md.currentMode = getModeAttribute(attributes, "name");
      // If already defined, report errors.
      if (md.currentMode.isDefined()) {
        error("duplicate_mode", md.currentMode.getName());
        error("first_mode", md.currentMode.getName(), md.currentMode.getWhereDefined());
      }
      else {
        // Check if we have a base mode and set that as the base mode for this mode.
        Mode base = getModeAttribute(attributes, "extends");
        if (base != null)
          md.currentMode.setBaseMode(base);
        // record the location where this mode is defined.
        md.currentMode.noteDefined(locator);
      }
    }

    /**
     * Parse a mode element.
     * @param attributes The element attributes.
     * @throws SAXException
     */
    private void parseIncludedMode(Attributes attributes) throws SAXException {
      // Create an anonymous mode.
      Mode parent = md.currentMode;
      modeDataStack.push(md);
      md = new ModeData();
      md.currentMode = new Mode(defaultBaseMode);
      md.currentMode.noteDefined(locator);
      parent.addIncludedMode(md.currentMode);
    }

    /**
     * Parse a mode element.
     * @param attributes The element attributes.
     * @throws SAXException
     */
    private void parseNestedMode(Attributes attributes) throws SAXException {
      // Nested mode is an anonymous mode inside an action. The action does
    	// not have a useMode attribute and we alrady have the mode for that
    	// created in the current mode data lastMode, so we use that and define it
    	// as this nested mode.
      ModeData oldMd = md;
      modeDataStack.push(md);
      md = new ModeData();
      md.currentMode = oldMd.lastMode;
      // If already defined, report errors.
      if (md.currentMode.isDefined()) {
        error("duplicate_mode", md.currentMode.getName());
        error("first_mode", md.currentMode.getName(), md.currentMode.getWhereDefined());
      }
      else {
        // record the location where this mode is defined.
        md.currentMode.noteDefined(locator);
      }
    }

    /**
     * Parse a namespace rule.
     * @param attributes The namespace element attributes.
     * @throws SAXException
     */
    private void parseNamespace(Attributes attributes) throws SAXException {
      md.anyNamespace = false;
      parseRule(getNs(attributes), attributes);
    }

    /**
     * Parse an anyNamespace rule.
     * @param attributes The anyNamespace element attributes.
     * @throws SAXException
     */
    private void parseAnyNamespace(Attributes attributes) throws SAXException {
      md.anyNamespace = true;
      parseRule(NamespaceSpecification.ANY_NAMESPACE, attributes);
    }

    /**
     * Parse namespace and anyNamespace rules/
     * @param ns The namespace, ##any for anyNamespace
     * @param attributes The rule attributes.
     * @throws SAXException
     */
    private void parseRule(String ns, Attributes attributes) throws SAXException {
      // gets the value of the match attribute, defaults to match elements only.
      md.match = toElementsOrAttributes(attributes.getValue("", "match"),
                                        ElementsOrAttributes.ELEMENTS);
      String wildcard = attributes.getValue("", "wildCard");
      if (wildcard == null) {
        wildcard = NamespaceSpecification.DEFAULT_WILDCARD;
      }

      // check if match attributes
      if (md.match.containsAttributes()) {
        // creates an empty attributes action set.
        md.attributeActions = new AttributeActionSet();
        // if we already have attribute actions for this namespace
        // signal an error.
        if (!md.currentMode.bindAttribute(ns, wildcard, md.attributeActions)) {
          if (ns.equals(NamespaceSpecification.ANY_NAMESPACE))
            error("duplicate_attribute_action_any_namespace");
          else
            error("duplicate_attribute_action", ns);
        }
      }
      else
        md.attributeActions = null;
      // XXX: george // } else md.attributeActions=null; //???

      // check if match elements
      if (md.match.containsElements()) {
        // creates an empty action set.
        md.actions = new ActionSet();
        // if we already have actions for this namespace
        // signal an error.
        if (!md.currentMode.bindElement(ns, wildcard, md.actions)) {
          if (ns.equals(NamespaceSpecification.ANY_NAMESPACE))
            error("duplicate_element_action_any_namespace");
          else
            error("duplicate_element_action", ns);
        }
      }
      else
        md.actions = null;
    }

    /**
     * Parse a validate action.
     * @param attributes The validate element attributes.
     * @throws SAXException
     */
    private void parseValidate(Attributes attributes) throws SAXException {
      // get the resolved URI pointing to the schema.
      md.schemaUriRef = getSchema(attributes);
      md.schemaUriBase = xmlBaseHandler.getBaseUri();
      // get the schema type
      md.schemaType = getSchemaType(attributes);
      // if no schemaType attribute, use the default schema type.
      if (md.schemaType == null)
        md.schemaType = defaultSchemaType;
      if (SchemaReceiverImpl.LEGACY_RNC_MEDIA_TYPE.equalsIgnoreCase(md.schemaType))
        warning("legacy_rnc_media_type", locator);
      // if we matched on elements create a mode usage.
      if (md.actions != null)
        md.modeUsage = getModeUsage(attributes);
      else
        md.modeUsage = null;
      // prepare to receive validate options.
      md.options = new PropertyMapBuilder();
      md.mustSupportOptions.clear();
    }

    /**
     * Notification that the validate element ends.
     * @throws SAXException
     */
    private void finishValidate() throws SAXException {
      if (md.schemaUriRef != null) {
        try {
          // if we had attribute actions, that is matching attributes
          // we add a schema to the attributes action set.
          if (md.attributeActions != null) {
            Schema schema = createSubSchema(true);
            md.attributeActions.addSchema(schema);
          }
          // if we had element actions, that is macting elements
          // we add a validate action with the schema and the specific mode usage.
          if (md.actions != null) {
            Schema schema = createSubSchema(false);
            md.actions.addNoResultAction(new ValidateAction(md.modeUsage, schema));
          }
        }
        catch (IncorrectSchemaException e) {
          hadError = true;
        }
        catch (IOException e) {
          throw new WrappedIOException(e);
        }
      }
    }

    /**
     * Notification that the mode element ends.
     * @throws SAXException
     */
    private void finishMode() throws SAXException {
    }

    /**
     * Notification that the mode element ends.
     * @throws SAXException
     */
    private void finishIncludedMode() throws SAXException {
      md = (ModeData)modeDataStack.pop();
    }

    /**
     * Notification that the mode element ends.
     * @throws SAXException
     */
    private void finishNestedMode() throws SAXException {
      md = (ModeData)modeDataStack.pop();
    }

    /**
     * Creates a sub schema for the ending validate action (this is
     * called from finishValidate).
     *
     * @param isAttributesSchema If the schema is intended to validate only attributes.
     * @return A Schema.
     * @throws IOException
     * @throws IncorrectSchemaException
     * @throws SAXException
     */
    private Schema createSubSchema(boolean isAttributesSchema) throws IOException, IncorrectSchemaException, SAXException {
      // the user specified options
      PropertyMap requestedProperties = md.options.toPropertyMap();
      // let the schema receiver create a child schema
      Schema schema = sr.createChildSchema(md.schemaUriRef,
                                           md.schemaUriBase,
                                           md.schemaType,
                                           requestedProperties,
                                           isAttributesSchema);
      // get the schema properties
      PropertyMap actualProperties = schema.getProperties();
      // Check if the actual properties match the must support properties.
      for (Enumeration e = md.mustSupportOptions.elements(); e.hasMoreElements();) {
        MustSupportOption mso = (MustSupportOption)e.nextElement();
        Object actualValue = actualProperties.get(mso.pid);
        if (actualValue == null)
          error("unsupported_option", mso.name, mso.locator);
        else if (!actualValue.equals(requestedProperties.get(mso.pid)))
          error("unsupported_option_arg", mso.name, mso.locator);
      }
      return schema;
    }

    /**
     * Parse a validate option.
     * @param attributes The option element attributes.
     * @throws SAXException
     */
    private void parseOption(Attributes attributes) throws SAXException {
      // get the mustSupport flag
      boolean mustSupport;
      String mustSupportValue = attributes.getValue("", "mustSupport");
      if (mustSupportValue != null) {
        mustSupportValue = mustSupportValue.trim();
        mustSupport = mustSupportValue.equals("1") || mustSupportValue.equals("true");
      }
      else
        mustSupport = false;
      // Resolve the option if specified relative to the NVDL URI.
      String name = Uri.resolve(NVDL_URI, attributes.getValue("", "name"));
      Option option = sr.getOption(name);
      // check if we got a known option.
      if (option == null) {
        if (mustSupport)
          error("unknown_option", name);
      }
      else {
      // known option, look for arguments
        String arg = attributes.getValue("", "arg");
        try {
          PropertyId pid = option.getPropertyId();
          Object value = option.valueOf(arg);
          Object oldValue = md.options.get(pid);
          if (oldValue != null) {
            value = option.combine(new Object[]{oldValue, value});
            if (value == null)
              error("duplicate_option", name);
            else
              md.options.put(pid, value);
          }
          else {
            md.options.put(pid, value);
            md.mustSupportOptions.addElement(new MustSupportOption(name, pid,
                                                                locator == null
                                                                ? null
                                                                : new LocatorImpl(locator)));
          }
        }
        catch (OptionArgumentPresenceException e) {
          error(arg == null ? "option_requires_argument" : "option_unexpected_argument", name);
        }
        catch (OptionArgumentException e) {
          if (arg == null)
            error("option_requires_argument", name);
          else
            error("option_bad_argument", name, arg);
        }
      }
    }

    /**
     * Parse a trigger element.
     * @param attributes The trigger element attributes.
     * @throws SAXException
     */
    private void parseTrigger(Attributes attributes) throws SAXException {
      // get the ns and nameList, we know they are not null as we validate against the nvdl.rng schema.
      String ns = attributes.getValue("", "ns");
      String nameList = attributes.getValue("", "nameList");
      StringTokenizer st = new StringTokenizer(nameList);
      Set names = new HashSet(st.countTokens());
      while (st.hasMoreTokens()) {
        names.add(st.nextToken());
      }
      triggers.add(new Trigger(ns, names));
    }

    /**
     * Parse an attach action.
     * @param attributes The attach element attributes.
     */
    private void parseAttach(Attributes attributes) {
      // if the rule matched attributes set the attach flag in the attribute actions.
      if (md.attributeActions != null)
        md.attributeActions.setAttach(true);
      // if the rule matched elements, the the mode usage and create a attach result action
      // with that mode usage.
      if (md.actions != null) {
        md.modeUsage = getModeUsage(attributes);
        md.actions.setResultAction(new AttachAction(md.modeUsage));
      }
      // no element action -> no modeUsage.
      else
        md.modeUsage = null;
    }

    /**
     * Parse an unwrap action.
     * @param attributes The unwrap element attributes.
     */
    private void parseUnwrap(Attributes attributes) {
      // this makes sense only on elements
      // if we have element actions, create the mode usage and add
      // an unwrap action with this mode usage.
      if (md.actions != null) {
        md.modeUsage = getModeUsage(attributes);
        md.actions.setResultAction(new UnwrapAction(md.modeUsage));
      }
      // no element actions, no modeUsage.
      else
        md.modeUsage = null;
    }

    /**
     * Parse an attachPlaceholder action.
     * @param attributes The attachPlaceholder element attributes.
     */
    private void parseAttachPlaceholder(Attributes attributes) {
      // this makes sense only on elements
      // if we have element actions, create the mode usage and add
      // an attachPlaceholder action with this mode usage.
      if (md.actions != null) {
        md.modeUsage = getModeUsage(attributes);
        md.actions.setResultAction(new AttachPlaceholderAction(md.modeUsage));
      }
      // no element actions, no modeUsage.
      else
        md.modeUsage = null;
    }

    /**
     * Parse an allow action.
     *
     * @param attributes The allow element attributes.
     */
    private void parseAllow(Attributes attributes) {
      // if we match on elements, create the mode usage and add an allow action.
      if (md.actions != null) {
        md.modeUsage = getModeUsage(attributes);
        md.actions.addNoResultAction(new AllowAction(md.modeUsage));
      }
      // no actions, no mode usage.
      else
        md.modeUsage = null;
      // no need to add anything in the attribute actions, allow
      // is equivalent with a noop action.
    }

    /**
     * Parse a reject action.
     * @param attributes The reject element attributes.
     */
    private void parseReject(Attributes attributes) {
      // if element actions, get the mode usage and add a reject
      // action with this mode usage.
      if (md.actions != null) {
        md.modeUsage = getModeUsage(attributes);
        md.actions.addNoResultAction(new RejectAction(md.modeUsage));
      }
      // no actions, no mode usage
      else
        md.modeUsage = null;
      // if attribute actions, set the reject flag.
      if (md.attributeActions != null)
        md.attributeActions.setReject(true);
    }

    /**
     * Parse a cancel nested actions action.
     *
     * @param attributes The cancelNestedActions element attributes.
     */
    private void parseCancelNestedActions(Attributes attributes) {
      // if we match on elements, create the mode usage and add a
      // cancelNestedActions action.
      if (md.actions != null) {
        md.modeUsage = getModeUsage(attributes);
        md.actions.setCancelNestedActions(true);
      }
      // no actions, no mode usage.
      else
        md.modeUsage = null;

      // if attribute actions set the cancelNestedActions flag.
      if (md.attributeActions != null) {
        md.attributeActions.setCancelNestedActions(true);
      }
    }

    /**
     * Parse context dependent mode usages.
     * @param attributes The context element attributes.
     * @throws SAXException
     */
    private void parseContext(Attributes attributes) throws SAXException {
      // TODO: check this in the NVDL spec.
      // context not allowed within anyNamespace.???
      // IT SEEMS IT IS ALLOWED IN NVDL...
      //if (md.anyNamespace) {
      //  error("context_any_namespace");
      //  return;
      //}
      // Get the mode to be used further on this context.
      Mode mode = getUseMode(attributes);
      md.lastMode = mode;
      try {
        // parse the path value into a list of Path objects
        // and add them to the mode usage
        Vector paths = Path.parse(attributes.getValue("", "path"));
        // XXX warning if modeUsage is null
        if (md.modeUsage != null) {
          for (int i = 0, len = paths.size(); i < len; i++) {
            Path path = (Path)paths.elementAt(i);
            if (!md.modeUsage.addContext(path.isRoot(), path.getNames(), mode))
              error("duplicate_path", path.toString());
          }
        }
      }
      catch (Path.ParseException e) {
        error(e.getMessageKey());
      }
    }

    /**
     * Get the URI specified by a schema attribute and if we have a
     * relative location resolve that against the base URI taking into
     * account also eventual xml:base attributes.
     * @param attributes The validate element attributes.
     * @return A resolved URI as string.
     * @throws SAXException If the schema contains a fragment id.
     */
    private String getSchema(Attributes attributes) throws SAXException {
      String schemaUri = attributes.getValue("", "schema");
      if ("".equals(schemaUri)) {
        error("no_schema");
        schemaUri = null;
      }
      if (schemaUri != null) {
        if (Uri.hasFragmentId(schemaUri))
          error("schema_fragment_id");
        return schemaUri;
      }
      return null;
    }

    /**
     * Get the schema type
     * @param attributes The attributes
     * @return The value of the schemaType attribute.
     */
    private String getSchemaType(Attributes attributes) {
      return attributes.getValue("", "schemaType");
    }

    /**
     * Get an ElementsOrAttributes instance depending on the match attribute value.
     * @param value The match attribute value.
     * @param defaultValue The default value if value is null.
     * @return an ElementsOrAttributes constant.
     */
    private ElementsOrAttributes toElementsOrAttributes(String value, ElementsOrAttributes defaultValue) {
      if (value == null)
        return defaultValue;
      ElementsOrAttributes eoa = ElementsOrAttributes.NEITHER;
      if (value.indexOf("elements") >= 0)
        eoa = eoa.addElements();
      if (value.indexOf("attributes") >= 0)
        eoa = eoa.addAttributes();
      return eoa;
    }

    /**
     * Creates a mode usage that matches current mode and uses further
     * the mode specified by the useMode attribute.
     * @param attributes The action element attributes.
     * @return A mode usage from currentMode to the mode specified
     * by the useMode attribute.
     */
    private ModeUsage getModeUsage(Attributes attributes) {
      md.lastMode = getUseMode(attributes);
      return new ModeUsage(md.lastMode, md.currentMode);
    }

    /**
     * Get the Mode for the useMode attribute.
     * @param attributes the attributes
     * @return the mode with the useMode name or the special Mode.CURRENT mode that
     * will be resolved to the current mode in a Mode usage.
     */
    private Mode getUseMode(Attributes attributes) {
      Mode mode = getModeAttribute(attributes, "useMode");
      if (mode == null)
        return new Mode(defaultBaseMode);
      mode.noteUsed(locator);
      return mode;
    }

    /**
     * Get the namespace from the ns attribute.
     * Also check that the namespace is an absolute URI and report an
     * error otherwise.
     * @param attributes The list of attributes of the namespace element
     * @return The ns value.
     * @throws SAXException
     */
    private String getNs(Attributes attributes) throws SAXException {
      String ns = attributes.getValue("", "ns");
      if (ns != null && !Uri.isAbsolute(ns) && !ns.equals(""))
        error("ns_absolute");
      return ns;
    }

    /**
     * Report a no arguments error from a key.
     * @param key The error key.
     * @throws SAXException
     */
    void error(String key) throws SAXException {
      hadError = true;
      if (eh == null)
        return;
      eh.error(new SAXParseException(localizer.message(key), locator));
    }

    /**
     * Report an one argument error.
     * @param key The error key.
     * @param arg The argument.
     * @throws SAXException
     */
    void error(String key, String arg) throws SAXException {
      hadError = true;
      if (eh == null)
        return;
      eh.error(new SAXParseException(localizer.message(key, arg), locator));
    }

    /**
     * Report an one argument error with location.
     * @param key The error key.
     * @param arg The argument.
     * @param locator The location.
     * @throws SAXException
     */
    void error(String key, String arg, Locator locator) throws SAXException {
      hadError = true;
      if (eh == null)
        return;
      eh.error(new SAXParseException(localizer.message(key, arg), locator));
    }

    /**
     * Report a two arguments error.
     * @param key The error key.
     * @param arg1 The first argument.
     * @param arg2 The second argument.
     * @throws SAXException
     */
    void error(String key, String arg1, String arg2) throws SAXException {
      hadError = true;
      if (eh == null)
        return;
      eh.error(new SAXParseException(localizer.message(key, arg1, arg2), locator));
    }

    /**
     * Report a no argument warning with location.
     * @param key The warning key.
     * @param locator The location.
     * @throws SAXException
     */
    void warning(String key, Locator locator) throws SAXException {
      if (eh == null)
        return;
      eh.warning(new SAXParseException(localizer.message(key), locator));
    }
  }
  /**
   * Creates a NVDL schema implementation.
   * Initializes the attributesSchema flag and the built in modes.
   * @param properties Properties.
   */
  SchemaImpl(PropertyMap properties) {
    super(properties);
    this.attributesSchema = properties.contains(WrapProperty.ATTRIBUTE_OWNER);
    makeBuiltinMode("#allow", AllowAction.class);
    makeBuiltinMode("#attach", AttachAction.class);
    makeBuiltinMode("#unwrap", UnwrapAction.class);
    defaultBaseMode = makeBuiltinMode("#reject", RejectAction.class);
  }

  /**
   * Makes a built in mode.
   * @param name The mode name.
   * @param cls The action class.
   * @return A Mode object.
   */
  private Mode makeBuiltinMode(String name, Class cls) {
    // lookup/create a mode with the given name.
    Mode mode = lookupCreateMode(name);
    // Init the element action set for this mode.
    ActionSet actions = new ActionSet();
    // from the current mode we will use further the built in mode.
    ModeUsage modeUsage = new ModeUsage(Mode.CURRENT, mode);
    // Add the action corresponding to the built in mode.
    if (cls == AttachAction.class)
      actions.setResultAction(new AttachAction(modeUsage));
    else if (cls == AllowAction.class)
      actions.addNoResultAction(new AllowAction(modeUsage));
    else if (cls == UnwrapAction.class)
      actions.setResultAction(new UnwrapAction(modeUsage));
    else
      actions.addNoResultAction(new RejectAction(modeUsage));
    // set the actions on any namespace.
    mode.bindElement(NamespaceSpecification.ANY_NAMESPACE, NamespaceSpecification.DEFAULT_WILDCARD, actions);
    // the mode is not defined in the script explicitelly
    mode.noteDefined(null);
    // creates attribute actions
    AttributeActionSet attributeActions = new AttributeActionSet();
    // if we have a schema for attributes then in the built in modes
    // we reject attributes by default
    // otherwise we attach attributes by default in the built in modes
    if (attributesSchema)
      attributeActions.setReject(true);
    else
      attributeActions.setAttach(true);
    // set the attribute actions on any namespace
    mode.bindAttribute(NamespaceSpecification.ANY_NAMESPACE, NamespaceSpecification.DEFAULT_WILDCARD, attributeActions);
    return mode;
  }

  /**
   * Installs the schema handler on the reader.
   *
   * @param in The reader.
   * @param sr The schema receiver.
   * @return The installed handler that implements also SchemaFuture.
   */
  SchemaFuture installHandlers(XMLReader in, SchemaReceiverImpl sr) {
    Handler h = new Handler(sr);
    in.setContentHandler(h);
    return h;
  }

  /**
   * Creates a Validator for validating XML documents against this
   * NVDL script.
   * @param properties properties.
   */
  public Validator createValidator(PropertyMap properties) {
    return new ValidatorImpl(startMode, triggers, properties);
  }

  /**
   * Get the mode specified by an attribute from no namespace.
   *
   * @param attributes The attributes.
   * @param localName The attribute name.
   * @return The mode refered by the licanName attribute.
   */
  private Mode getModeAttribute(Attributes attributes, String localName) {
    return lookupCreateMode(attributes.getValue("", localName));
  }

  /**
   * Gets a mode with the given name from the mode map.
   * If not present then it creates a new mode extending the default base mode.
   *
   * @param name The mode to look for or create if it does not exist.
   * @return Always a not null mode.
   */
  private Mode lookupCreateMode(String name) {
    if (name == null)
      return null;
    name = name.trim();
    Mode mode = (Mode)modeMap.get(name);
    if (mode == null) {
      mode = new Mode(name, defaultBaseMode);
      modeMap.put(name, mode);
    }
    return mode;
  }

}


text:
<record><header><identifier>froac:556</identifier><datestamp>2013-09-20T04:33:33Z</datestamp><setSpec>notImplemented</setSpec></header><metadata><lom:lom xmlns:lom="http://ltsc.ieee.org/xsd/LOM" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://ltsc.ieee.org/xsd/LOM http://ltsc.ieee.org/xsd/lomv1.0/lom.xsd">
<lom:general>
	<lom:title>Video objeto de aprendizaje CrazyTalk</lom:title>
	<lom:language>es</lom:language>
	<lom:description>Este vídeo presenta una breve muestra de lo que se puede lograr con la herramienta CrazyTalk, y la invitación a utilizarla para hacer objetos de Aprendizaje.</lom:description>
	<lom:keyword>CrazyTalk</lom:keyword>
	<lom:coverage>Herramientas Objetos de Aprendizaje</lom:coverage>
	<lom:structure> </lom:structure>
	<lom:aggregationlevel> </lom:aggregationlevel>
</lom:general>

<lom:lifecycle>
	<lom:version>1.0</lom:version>
	<lom:status>draft</lom:status>
	<lom:contribute>
		<lom:role>script writer</lom:role>
		<lom:date>2013-09-20</lom:date>
		<lom:entity>Mauricio Poveda Vergara</lom:entity>
		<lom:entity>Ricardo Uribe González</lom:entity>
	</lom:contribute>
</lom:lifecycle>

<lom:metametadata>
	<lom:metadataschema>LOMv1.0</lom:metadataschema>
	<lom:language>none</lom:language>
</lom:metametadata>

<lom:technical>
	<lom:format>wmv</lom:format>
	<lom:size>26635658</lom:size>
	<lom:location>http://froac.manizales.unal.edu.co/roap/control/download.php?id=448</lom:location>
	<lom:installationremarks> </lom:installationremarks>
	<lom:otherplatformrequirements> </lom:otherplatformrequirements>
	<lom:duration> </lom:duration>
</lom:technical>

<lom:educational>
	<lom:interactivitytype>2</lom:interactivitytype>
	<lom:learningresourcetype>graph</lom:learningresourcetype>
	<lom:interactivitylevel>high</lom:interactivitylevel>
	<lom:semanticdensity>low</lom:semanticdensity>
	<lom:intendedenduserrole>learner</lom:intendedenduserrole>
	<lom:context>training</lom:context>
	<lom:typicalagerange>10- 30</lom:typicalagerange>
	<lom:difficulty>easy</lom:difficulty>
	<lom:typicallearningtime> </lom:typicallearningtime>
	<lom:language>es</lom:language>
</lom:educational>

<lom:rights>
	<lom:cost>no</lom:cost>
	<lom:copyrightandotherrestrictions>yes</lom:copyrightandotherrestrictions>
	<lom:description> </lom:description>
</lom:rights>

<lom:relation>
	<lom:kind>references</lom:kind>
</lom:relation>

<lom:annotation>
	<lom:entity> </lom:entity>
	<lom:date> </lom:date>
	<lom:description> </lom:description>
</lom:annotation>

<lom:classification>
	<lom:purpose> </lom:purpose>
	<lom:description> </lom:description>
</lom:classification>
</lom:lom></metadata></record>

redpajama_set_name: RedPajamaGithub


text:
package jme3test.network;

import java.util.logging.Level;
import java.util.logging.Logger;

import com.jme3.network.*;
import com.jme3.network.serializing.Serializable;
import com.jme3.network.serializing.Serializer;
import java.io.IOException;

/**
 *  A simple test chat server.  When SM implements a set
 *  of standard chat classes this can become a lot simpler.
 *
 *  @version   $Revision$
 *  @author    Paul Speed
 */
public class TestChatServer {
    // Normally these and the initialized method would
    // be in shared constants or something.

    public static final String NAME = "Test Chat Server";
    public static final int VERSION = 1;
    public static final int PORT = 5110;
    public static final int UDP_PORT = 5110;

    private Server server;
    private boolean isRunning;

    public TestChatServer() throws IOException {

        // Use this to test the client/server name version check
        this.server = Network.createServer(NAME, VERSION, PORT, UDP_PORT);

        // Initialize our own messages only after the server has been created.
        // It registers some additional messages with the serializer by default
        // that need to go before custom messages.
        initializeClasses();

        ChatHandler handler = new ChatHandler();
        server.addMessageListener(handler, ChatMessage.class);

        server.addConnectionListener(new ChatConnectionListener());
    }

    public boolean isRunning() {
        return isRunning;
    }

    public synchronized void start() {
        if( isRunning ) {
            return;
        }
        server.start();
        isRunning = true;
    }

    public synchronized void close() {
        if( !isRunning ) {
            return;
        }

        // Gracefully let any connections know that the server is
        // going down.  Without this, their connections will simply
        // error out.
        for( HostedConnection conn : server.getConnections() ) {
            conn.close("Server is shutting down.");
        }
        try {
            Thread.sleep(1000); // wait a couple beats to let the messages go out
        } catch( InterruptedException e ) {
            e.printStackTrace();
        }

        server.close();
        isRunning = false;
        notifyAll();
    }

    protected void runCommand( HostedConnection conn, String user, String command ) {
        if( "/shutdown".equals(command) ) {
            server.broadcast(new ChatMessage("server", "Server is shutting down."));
            close();
        } else if( "/help".equals(command) ) {
            StringBuilder sb = new StringBuilder();
            sb.append("Chat commands:\n");
            sb.append("/help - prints this message.\n");
            sb.append("/shutdown - shuts down the server.");
            server.broadcast(new ChatMessage("server", sb.toString()));
        }
    }

    public static void initializeClasses() {
        // Doing it here means that the client code only needs to
        // call our initialize.
        Serializer.registerClass(ChatMessage.class);
    }

    public static void main(String... args) throws Exception {

        // Increase the logging level for networking...
        System.out.println("Setting logging to max");
        Logger networkLog = Logger.getLogger("com.jme3.network");
        networkLog.setLevel(Level.FINEST);

        // And we have to tell JUL's handler also
        // turn up logging in a very convoluted way
        Logger rootLog = Logger.getLogger("");
        if( rootLog.getHandlers().length > 0 ) {
            rootLog.getHandlers()[0].setLevel(Level.FINEST);
        }

        TestChatServer chatServer = new TestChatServer();
        chatServer.start();

        System.out.println("Waiting for connections on port:" + PORT);

        // Keep running basically forever
        while( chatServer.isRunning ) {
            synchronized (chatServer) {
                chatServer.wait();
            }
        }
    }

    private class ChatHandler implements MessageListener<HostedConnection> {

        public ChatHandler() {
        }

        @Override
        public void messageReceived(HostedConnection source, Message m) {
            if (m instanceof ChatMessage) {
                // Keep track of the name just in case we
                // want to know it for some other reason later, and it's
                // a good example of session data.
                ChatMessage cm = (ChatMessage)m;
                source.setAttribute("name", cm.getName());

                // Check for a / command
                if( cm.message.startsWith("/") ) {
                    runCommand(source, cm.name, cm.message);
                    return;
                }

                System.out.println("Broadcasting:" + m + "  reliable:" + m.isReliable());

                // Just rebroadcast... the reliable flag will stay the
                // same so if it came in on UDP it will go out on that too
                source.getServer().broadcast(cm);
            } else {
                System.err.println("Received odd message:" + m);
            }
        }
    }

    private class ChatConnectionListener implements ConnectionListener {

        @Override
        public void connectionAdded( Server server, HostedConnection conn ) {
            System.out.println("connectionAdded(" + conn + ")");
        }

        @Override
        public void connectionRemoved(Server server, HostedConnection conn) {
            System.out.println("connectionRemoved(" + conn + ")");
        }

    }

    @Serializable
    public static class ChatMessage extends AbstractMessage {

        private String name;
        private String message;

        public ChatMessage() {
        }

        public ChatMessage(String name, String message) {
            setName(name);
            setMessage(message);
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setMessage(String s) {
            this.message = s;
        }

        public String getMessage() {
            return message;
        }

        @Override
        public String toString() {
            return name + ":" + message;
        }
    }
}


text:
using System;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using Windows.Storage;
using UwpHelpers.Controls.Common;

namespace UwpHelpers.Controls.Extensions
{
    /// <summary>
    /// A set of extension methods for System.Net.Http.HttpClient. These can be used in PCLs (e.g. Xamarin apps).
    /// Note- Windows.Web.Http.HttpClient has support for Progress. If you do not need System.Net.Http, investigate the possibility of using Windows.Web.Http
    /// </summary>
    public static class HttpClientExtensions
    {
        /// <summary>
        /// Helper method to POST binary image data to an API endpoint that expects the data to be accompanied by a parameter
        /// </summary>
        /// <param name="client">HttpClient instance</param>
        /// <param name="imageFile">Valie StorageFile of the image</param>
        /// <param name="url">The API's http or https endpoint</param>
        /// <param name="progessReporter">Progress reporter to track progress of the download operation</param>
        /// <param name="parameterName">The name of the parameter the API expects the image data in</param>
        /// <returns></returns>
        public static async Task<string> SendImageDataWithDownloadProgressAsync(this HttpClient client, StorageFile imageFile, string url, string parameterName, IProgress<DownloadProgressArgs> progessReporter)
        {
            if (client == null)
                throw new ArgumentNullException(nameof(client), "HttpClient was null");

            if (string.IsNullOrEmpty(url))
                throw new ArgumentNullException(nameof(url), "You must set a URL for the the HttpClient");

            if (imageFile == null)
                throw new ArgumentNullException(nameof(imageFile), "You must have a valid StorageFile for this method to work");

            if (string.IsNullOrEmpty(parameterName))
                throw new ArgumentNullException(nameof(parameterName), "You must set a parameter name for the image data");

            if (progessReporter == null)
                throw new ArgumentNullException(nameof(progessReporter), "ProgressReporter was null");

            try
            {
                client.DefaultRequestHeaders.ExpectContinue = false;

                byte[] fileBytes;
                using (var fileStream = await imageFile.OpenStreamForReadAsync())
                {
                    var binaryReader = new BinaryReader(fileStream);
                    fileBytes = binaryReader.ReadBytes((int) fileStream.Length);
                }

                var multipartContent = new MultipartFormDataContent();
                multipartContent.Add(new ByteArrayContent(fileBytes), parameterName);

                using (var response = await client.PostAsync(new Uri(url), multipartContent))
                using (var stream = await response.Content.ReadAsStreamAsync())
                using (var memStream = new MemoryStream())
                {
                    int receivedBytes = 0;
                    var totalBytes = Convert.ToInt32(response.Content.Headers.ContentLength);

                    while (true)
                    {
                        var buffer = new byte[4096];
                        int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);

                        //write the current loop's bytes into the MemoryStream that will be returned
                        await memStream.WriteAsync(buffer, 0, bytesRead);

                        if (bytesRead == 0)
                        {
                            break;
                        }

                        receivedBytes += bytesRead;

                        var args = new DownloadProgressArgs(receivedBytes, receivedBytes);
                        progessReporter.Report(args);

                        Debug.WriteLine($"Progress: {receivedBytes} of {totalBytes} bytes read");
                    }

                    memStream.Position = 0;
                    var stringContent = new StreamReader(memStream);
                    return stringContent.ReadToEnd();
                }
            }
            finally
            {
                client.Dispose();
            }
        }

        /// <summary>
        /// Stand-in replacement for HttpClient.GetStreamAsync that can report download progress.
        /// </summary>
        /// <param name="client">HttpClient instance</param>
        /// <param name="url">Url of where to download the stream from</param>
        /// <param name="progessReporter">Progress reporter to track progress of the download operation</param>
        /// <returns>Stream result of the GET request</returns>
        public static async Task<Stream> DownloadStreamWithProgressAsync(this HttpClient client, string url, IProgress<DownloadProgressArgs> progessReporter)
        {
            if (client == null)
                throw new ArgumentNullException(nameof(client), "HttpClient was null");

            if (string.IsNullOrEmpty(url))
                throw new ArgumentNullException(nameof(url), "You must set a URL for the API endpoint");

            if (progessReporter == null)
                throw new ArgumentNullException(nameof(progessReporter), "ProgressReporter was null");

            try
            {
                client.DefaultRequestHeaders.ExpectContinue = false;

                using (var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
                using (var stream = await response.Content.ReadAsStreamAsync())
                {
                    int receivedBytes = 0;
                    var totalBytes = Convert.ToInt32(response.Content.Headers.ContentLength);

                    var memStream = new MemoryStream();

                    while (true)
                    {
                        var buffer = new byte[4096];
                        int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);

                        //write the current loop's bytes into the MemoryStream that will be returned
                        await memStream.WriteAsync(buffer, 0, bytesRead);

                        if (bytesRead == 0)
                        {
                            break;
                        }

                        receivedBytes += bytesRead;

                        var args = new DownloadProgressArgs(receivedBytes, totalBytes);
                        progessReporter.Report(args);
                    }

                    memStream.Position = 0;
                    return memStream;
                }
            }
            finally
            {
                client.Dispose();
            }
        }

        /// <summary>
        /// Stand-in replacement for HttpClient.GetStringAsync that can report download progress.
        /// </summary>
        /// <param name="client">HttpClient instance</param>
        /// <param name="url">Url of where to download the stream from</param>
        /// <param name="progessReporter">Progress reporter to track progress of the download operation</param>
        /// <returns>String result of the GET request</returns>
        public static async Task<string> DownloadStringWithProgressAsync(this HttpClient client, string url, IProgress<DownloadProgressArgs> progessReporter)
        {
            if (client == null)
                throw new ArgumentNullException(nameof(client), "HttpClient was null");

            if (string.IsNullOrEmpty(url))
                throw new ArgumentNullException(nameof(url), "You must set a URL for the API endpoint");

            if (progessReporter == null)
                throw new ArgumentNullException(nameof(progessReporter), "ProgressReporter was null");

            try
            {
                client.DefaultRequestHeaders.ExpectContinue = false;

                using (var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
                using (var stream = await response.Content.ReadAsStreamAsync())
                using (var memStream = new MemoryStream())
                {
                    int receivedBytes = 0;
                    var totalBytes = Convert.ToInt32(response.Content.Headers.ContentLength);

                    while (true)
                    {
                        var buffer = new byte[4096];
                        int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);

                        //write the current loop's bytes into the MemoryStream that will be returned
                        await memStream.WriteAsync(buffer, 0, bytesRead);

                        if (bytesRead == 0)
                        {
                            break;
                        }

                        receivedBytes += bytesRead;

                        var args = new DownloadProgressArgs(receivedBytes, totalBytes);
                        progessReporter.Report(args);
                    }

                    memStream.Position = 0;

                    var stringContent = new StreamReader(memStream);
                    return stringContent.ReadToEnd();
                }
            }
            finally
            {
                client.Dispose();
            }
        }
    }
}


text:
#ifndef BRIDGE_VALSTATS_H
#define BRIDGE_VALSTATS_H

#include <string>
#include <iostream>

#include "ValProfile.h"
#include "bconst.h"

using namespace std;

class ValStats
{
  private:

    enum ValSumm
    {
      BRIDGE_VAL_ALL = 0,
      BRIDGE_VAL_MINOR = 1,
      BRIDGE_VAL_PAVLICEK = 2,
      BRIDGE_VAL_MAJOR = 3,
      BRIDGE_VAL_SUMM_SIZE = 4
    };

    struct ValStat
    {
      ValProfile profile;
      unsigned count[BRIDGE_VAL_SUMM_SIZE];
    };

    ValStat stats[BRIDGE_FORMAT_LABELS_SIZE][BRIDGE_FORMAT_LABELS_SIZE];

    string posOrDash(const unsigned u) const;

    bool rowHasEntries(
      const ValStat stat[],
      const unsigned label) const;

    bool summRowHasEntries(
      const ValStat stat[],
      const unsigned summLabel) const;

    void printRow(
      ostream& fstr,
      const ValStat vstat[],
      const unsigned label) const;

    void printRows(
      ostream& fstr,
      const ValStat vstat[],
      const unsigned lower,
      const unsigned upper) const;

    void printSummRow(
      ostream& fstr,
      const ValStat vstat[],
      const string& header,
      const ValSumm summLabel) const;

  public:

    ValStats();

    ~ValStats();

    void reset();

    void add(
      const Format formatOrig,
      const Format formatRef,
      const ValProfile& prof);

    void operator += (const ValStats& statsIn);

    void print(
      ostream& fstr,
      const bool detailFlag = true) const;
};

#endif


text:
require 'spec_helper'

describe 'rackspace_rsyslog::client' do
  context "when node['rackspace_rsyslog']['config']['server_ip'] is not set" do
    before do
      Chef::Log.stub(:fatal)
      $stdout.stub(:puts)
    end

    it 'exits fatally' do
      expect { ChefSpec::Runner.new.converge('rackspace_rsyslog::client') }.to raise_error(SystemExit)
    end
  end

  let(:chef_run) do
    ChefSpec::Runner.new(platform: 'ubuntu', version: '12.04') do |node|
      node.set['rackspace_rsyslog']['config']['server_ip'] = server_ip
    end.converge('rackspace_rsyslog::client')
  end

  let(:server_ip) { "10.#{rand(1..9)}.#{rand(1..9)}.50" }
  let(:service_resource) { 'service[rsyslog]' }

  it 'includes the default recipe' do
    expect(chef_run).to include_recipe('rackspace_rsyslog::default')
  end

  context '/etc/rsyslog.d/49-remote.conf template' do
    let(:template) { chef_run.template('/etc/rsyslog.d/49-remote.conf') }

    it 'creates the template' do
      expect(chef_run).to render_file(template.path).with_content("*.* @@#{server_ip}:514")
    end

    it 'is owned by root:root' do
      expect(template.owner).to eq('root')
      expect(template.group).to eq('root')
    end

    it 'has 0644 permissions' do
      expect(template.mode).to eq('0644')
    end

    it 'notifies restarting the service' do
      expect(template).to notify(service_resource).to(:restart)
    end

  end

  context '/etc/rsyslog.d/server.conf file' do
    let(:file) { chef_run.file('/etc/rsyslog.d/server.conf') }

    it 'deletes the file' do
      expect(chef_run).to delete_file(file.path)
    end

    it 'notifies restarting the service' do
      expect(file).to notify(service_resource).to(:reload)
    end

  end
end


text:
class RenameShaAndExtColumns < ActiveRecord::Migration
  def up
    rename_column :optimized_images, :sha, :sha1
    change_column :optimized_images, :sha1, :string, limit: 40
    rename_column :optimized_images, :ext, :extension
    change_column :optimized_images, :extension, :string, limit: 10
  end

  def down
    change_column :optimized_images, :extension, :string, limit: 255
    rename_column :optimized_images, :extension, :ext
    change_column :optimized_images, :sha1, :string, limit: 255
    rename_column :optimized_images, :sha1, :sha
  end
end


text:
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_command_line.h"
#include "build/build_config.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/tabs/tab_enums.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/embedder_support/switches.h"
#include "components/javascript_dialogs/app_modal_dialog_manager.h"
#include "components/javascript_dialogs/tab_modal_dialog_manager.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/prerender_test_util.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_source.h"
#include "third_party/blink/public/common/features.h"

using DismissalCause =
    javascript_dialogs::TabModalDialogManager::DismissalCause;

class JavaScriptDialogTest : public InProcessBrowserTest {
 public:
  void SetUpOnMainThread() override {
    InProcessBrowserTest::SetUpOnMainThread();
    host_resolver()->AddRule("*", "127.0.0.1");
    ASSERT_TRUE(embedded_test_server()->Start());
  }

 private:
  friend class JavaScriptDialogDismissalCauseTester;
};

IN_PROC_BROWSER_TEST_F(JavaScriptDialogTest, ReloadDoesntHang) {
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  javascript_dialogs::TabModalDialogManager* js_helper =
      javascript_dialogs::TabModalDialogManager::FromWebContents(tab);

  // Show a dialog.
  scoped_refptr<content::MessageLoopRunner> runner =
      new content::MessageLoopRunner;
  js_helper->SetDialogShownCallbackForTesting(runner->QuitClosure());
  tab->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(u"alert()",
                                                        base::NullCallback());
  runner->Run();

  // Try reloading.
  tab->GetController().Reload(content::ReloadType::NORMAL, false);
  EXPECT_TRUE(content::WaitForLoadStop(tab));

  // If the WaitForLoadStop doesn't hang forever, we've passed.
}

IN_PROC_BROWSER_TEST_F(JavaScriptDialogTest,
                       ClosingPageSharingRendererDoesntHang) {
  // Turn off popup blocking.
  base::test::ScopedCommandLine scoped_command_line;
  scoped_command_line.GetProcessCommandLine()->AppendSwitch(
      embedder_support::kDisablePopupBlocking);

  // Two tabs, one render process.
  content::WebContents* tab1 =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::WebContentsAddedObserver new_wc_observer;
  tab1->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
      u"window.open('about:blank');", base::NullCallback());
  content::WebContents* tab2 = new_wc_observer.GetWebContents();
  ASSERT_NE(tab1, tab2);
  ASSERT_EQ(tab1->GetPrimaryMainFrame()->GetProcess(),
            tab2->GetPrimaryMainFrame()->GetProcess());

  // Tab two shows a dialog.
  scoped_refptr<content::MessageLoopRunner> runner =
      new content::MessageLoopRunner;
  javascript_dialogs::TabModalDialogManager* js_helper2 =
      javascript_dialogs::TabModalDialogManager::FromWebContents(tab2);
  js_helper2->SetDialogShownCallbackForTesting(runner->QuitClosure());
  tab2->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(u"alert()",
                                                         base::NullCallback());
  runner->Run();

  // Tab two is closed while the dialog is up.
  int tab2_index = browser()->tab_strip_model()->GetIndexOfWebContents(tab2);
  browser()->tab_strip_model()->CloseWebContentsAt(tab2_index,
                                                   TabCloseTypes::CLOSE_NONE);

  // Try reloading tab one.
  tab1->GetController().Reload(content::ReloadType::NORMAL, false);
  EXPECT_TRUE(content::WaitForLoadStop(tab1));

  // If the WaitForLoadStop doesn't hang forever, we've passed.
}

IN_PROC_BROWSER_TEST_F(JavaScriptDialogTest,
                       ClosingPageWithSubframeAlertingDoesntCrash) {
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  javascript_dialogs::TabModalDialogManager* js_helper =
      javascript_dialogs::TabModalDialogManager::FromWebContents(tab);

  // A subframe shows a dialog.
  std::string dialog_url = "data:text/html,";
  std::string script = "var iframe = document.createElement('iframe');"
                       "iframe.src = '" + dialog_url + "';"
                       "document.body.appendChild(iframe);";
  scoped_refptr<content::MessageLoopRunner> runner =
      new content::MessageLoopRunner;
  js_helper->SetDialogShownCallbackForTesting(runner->QuitClosure());
  tab->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
      base::UTF8ToUTF16(script), base::NullCallback());
  runner->Run();

  // The tab is closed while the dialog is up.
  int tab_index = browser()->tab_strip_model()->GetIndexOfWebContents(tab);
  browser()->tab_strip_model()->CloseWebContentsAt(tab_index,
                                                   TabCloseTypes::CLOSE_NONE);

  // No crash is good news.
}

class JavaScriptCallbackHelper {
 public:
  javascript_dialogs::TabModalDialogManager::DialogClosedCallback
  GetCallback() {
    return base::BindOnce(&JavaScriptCallbackHelper::DialogClosed,
                          base::Unretained(this));
  }

  bool last_success() { return last_success_; }
  std::u16string last_input() { return last_input_; }

 private:
  void DialogClosed(bool success, const std::u16string& user_input) {
    last_success_ = success;
    last_input_ = user_input;
  }

  bool last_success_;
  std::u16string last_input_;
};

// Tests to make sure HandleJavaScriptDialog works correctly.
IN_PROC_BROWSER_TEST_F(JavaScriptDialogTest, HandleJavaScriptDialog) {
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::RenderFrameHost* frame = tab->GetPrimaryMainFrame();
  javascript_dialogs::TabModalDialogManager* js_helper =
      javascript_dialogs::TabModalDialogManager::FromWebContents(tab);

  JavaScriptCallbackHelper callback_helper;

  // alert
  bool did_suppress = false;
  js_helper->RunJavaScriptDialog(
      tab, frame, content::JAVASCRIPT_DIALOG_TYPE_ALERT, std::u16string(),
      std::u16string(), callback_helper.GetCallback(), &did_suppress);
  ASSERT_TRUE(js_helper->IsShowingDialogForTesting());
  js_helper->HandleJavaScriptDialog(tab, true, nullptr);
  ASSERT_FALSE(js_helper->IsShowingDialogForTesting());
  ASSERT_TRUE(callback_helper.last_success());
  ASSERT_EQ(std::u16string(), callback_helper.last_input());

  // confirm
  for (auto response : {true, false}) {
    js_helper->RunJavaScriptDialog(
        tab, frame, content::JAVASCRIPT_DIALOG_TYPE_CONFIRM, std::u16string(),
        std::u16string(), callback_helper.GetCallback(), &did_suppress);
    ASSERT_TRUE(js_helper->IsShowingDialogForTesting());
    js_helper->HandleJavaScriptDialog(tab, response, nullptr);
    ASSERT_FALSE(js_helper->IsShowingDialogForTesting());
    ASSERT_EQ(response, callback_helper.last_success());
    ASSERT_EQ(std::u16string(), callback_helper.last_input());
  }

  // prompt, cancel
  js_helper->RunJavaScriptDialog(
      tab, frame, content::JAVASCRIPT_DIALOG_TYPE_PROMPT, u"Label",
      std::u16string(), callback_helper.GetCallback(), &did_suppress);
  ASSERT_TRUE(js_helper->IsShowingDialogForTesting());
  js_helper->HandleJavaScriptDialog(tab, false, nullptr);
  ASSERT_FALSE(js_helper->IsShowingDialogForTesting());
  ASSERT_FALSE(callback_helper.last_success());
  ASSERT_EQ(std::u16string(), callback_helper.last_input());

  std::u16string value1 = u"abc";
  std::u16string value2 = u"123";

  // prompt, ok + override
  js_helper->RunJavaScriptDialog(
      tab, frame, content::JAVASCRIPT_DIALOG_TYPE_PROMPT, u"Label", value1,
      callback_helper.GetCallback(), &did_suppress);
  ASSERT_TRUE(js_helper->IsShowingDialogForTesting());
  js_helper->HandleJavaScriptDialog(tab, true, &value2);
  ASSERT_FALSE(js_helper->IsShowingDialogForTesting());
  ASSERT_TRUE(callback_helper.last_success());
  ASSERT_EQ(value2, callback_helper.last_input());

  // prompt, ok + no override
  js_helper->RunJavaScriptDialog(
      tab, frame, content::JAVASCRIPT_DIALOG_TYPE_PROMPT, u"Label", value1,
      callback_helper.GetCallback(), &did_suppress);
  ASSERT_TRUE(js_helper->IsShowingDialogForTesting());
  js_helper->HandleJavaScriptDialog(tab, true, nullptr);
  ASSERT_FALSE(js_helper->IsShowingDialogForTesting());
  ASSERT_TRUE(callback_helper.last_success());
  ASSERT_EQ(value1, callback_helper.last_input());
}

class JavaScriptDialogDismissalCauseTester {
 public:
  explicit JavaScriptDialogDismissalCauseTester(JavaScriptDialogTest* test)
      : tab_(test->browser()->tab_strip_model()->GetActiveWebContents()),
        frame_(tab_->GetPrimaryMainFrame()),
        js_helper_(
            javascript_dialogs::TabModalDialogManager::FromWebContents(tab_)) {
    js_helper_->SetDialogDismissedCallbackForTesting(base::BindOnce(
        &JavaScriptDialogDismissalCauseTester::SetLastDismissalCause,
        weak_factory_.GetWeakPtr()));
  }

  void PopupDialog(content::JavaScriptDialogType type) {
    bool did_suppress = false;
    js_helper_->RunJavaScriptDialog(tab_, frame_, type, u"Label", u"abc", {},
                                    &did_suppress);
  }

  void ClickDialogButton(bool accept, const std::u16string& user_input) {
    EXPECT_TRUE(js_helper_->IsShowingDialogForTesting());
    js_helper_->ClickDialogButtonForTesting(accept, user_input);
  }

  void Reload() {
    tab_->GetController().Reload(content::ReloadType::NORMAL, false);
    EXPECT_TRUE(content::WaitForLoadStop(tab_));
  }

  void CallHandleDialog(bool accept, const std::u16string* prompt_override) {
    EXPECT_TRUE(js_helper_->IsShowingDialogForTesting());
    js_helper_->HandleJavaScriptDialog(tab_, accept, prompt_override);
  }

  void CallCancelDialogs(bool reset_state) {
    EXPECT_TRUE(js_helper_->IsShowingDialogForTesting());
    js_helper_->CancelDialogs(tab_, reset_state);
  }

  absl::optional<DismissalCause> GetLastDismissalCause() {
    return dismissal_cause_;
  }

  void SetLastDismissalCause(DismissalCause cause) { dismissal_cause_ = cause; }

 private:
  raw_ptr<content::WebContents> tab_;
  raw_ptr<content::RenderFrameHost> frame_;
  raw_ptr<javascript_dialogs::TabModalDialogManager> js_helper_;

  absl::optional<DismissalCause> dismissal_cause_;

  base::WeakPtrFactory<JavaScriptDialogDismissalCauseTester> weak_factory_{
      this};
};

IN_PROC_BROWSER_TEST_F(JavaScriptDialogTest, DismissalCausePromptAcceptButton) {
  JavaScriptDialogDismissalCauseTester tester(this);
  tester.PopupDialog(content::JAVASCRIPT_DIALOG_TYPE_PROMPT);
  tester.ClickDialogButton(true, std::u16string());
  EXPECT_EQ(DismissalCause::kDialogButtonClicked,
            tester.GetLastDismissalCause());
}

IN_PROC_BROWSER_TEST_F(JavaScriptDialogTest, DismissalCausePromptCancelButton) {
  JavaScriptDialogDismissalCauseTester tester(this);
  tester.PopupDialog(content::JAVASCRIPT_DIALOG_TYPE_PROMPT);
  tester.ClickDialogButton(false, std::u16string());
  EXPECT_EQ(DismissalCause::kDialogButtonClicked,
            tester.GetLastDismissalCause());
}

IN_PROC_BROWSER_TEST_F(JavaScriptDialogTest, DismissalCausePromptHandleDialog) {
  JavaScriptDialogDismissalCauseTester tester(this);
  tester.PopupDialog(content::JAVASCRIPT_DIALOG_TYPE_PROMPT);
  tester.CallHandleDialog(true, nullptr);
  EXPECT_EQ(DismissalCause::kHandleDialogCalled,
            tester.GetLastDismissalCause());
}

IN_PROC_BROWSER_TEST_F(JavaScriptDialogTest,
                       DismissalCausePromptCancelDialogs) {
  JavaScriptDialogDismissalCauseTester tester(this);
  tester.PopupDialog(content::JAVASCRIPT_DIALOG_TYPE_PROMPT);
  tester.CallCancelDialogs(false);
  EXPECT_EQ(DismissalCause::kCancelDialogsCalled,
            tester.GetLastDismissalCause());
}

IN_PROC_BROWSER_TEST_F(JavaScriptDialogTest,
                       DismissalCausePromptTabClosedByUser) {
  JavaScriptDialogDismissalCauseTester tester(this);
  tester.PopupDialog(content::JAVASCRIPT_DIALOG_TYPE_PROMPT);
  chrome::CloseTab(browser());
// There are differences in the implementations of Views on different platforms
// that cause different dismissal causes.
#if BUILDFLAG(IS_MAC)
  // On MacOS 10.13, |kDialogClosed| is logged, while for other versions
  // |kCancelDialogsCalled| is logged. Expect only one but not both.
  EXPECT_TRUE(tester.GetLastDismissalCause() ==
                  DismissalCause::kCancelDialogsCalled xor
              tester.GetLastDismissalCause() == DismissalCause::kDialogClosed);
#else
  EXPECT_EQ(DismissalCause::kDialogClosed, tester.GetLastDismissalCause());
#endif
}

IN_PROC_BROWSER_TEST_F(JavaScriptDialogTest, DismissalCausePromptTabHidden) {
  JavaScriptDialogDismissalCauseTester tester(this);
  tester.PopupDialog(content::JAVASCRIPT_DIALOG_TYPE_PROMPT);
  chrome::NewTab(browser());
  EXPECT_EQ(DismissalCause::kTabHidden, tester.GetLastDismissalCause());
}

IN_PROC_BROWSER_TEST_F(JavaScriptDialogTest,
                       DismissalCausePromptBrowserSwitched) {
  JavaScriptDialogDismissalCauseTester tester(this);
  tester.PopupDialog(content::JAVASCRIPT_DIALOG_TYPE_PROMPT);
  chrome::NewEmptyWindow(browser()->profile());
  EXPECT_EQ(DismissalCause::kBrowserSwitched, tester.GetLastDismissalCause());
}

IN_PROC_BROWSER_TEST_F(JavaScriptDialogTest, DismissalCausePromptTabNavigated) {
  JavaScriptDialogDismissalCauseTester tester(this);
  tester.PopupDialog(content::JAVASCRIPT_DIALOG_TYPE_PROMPT);
  tester.Reload();
  EXPECT_EQ(DismissalCause::kTabNavigated, tester.GetLastDismissalCause());
}

IN_PROC_BROWSER_TEST_F(JavaScriptDialogTest,
                       DismissalCausePromptSubsequentDialogShown) {
  JavaScriptDialogDismissalCauseTester tester(this);
  tester.PopupDialog(content::JAVASCRIPT_DIALOG_TYPE_PROMPT);
  tester.PopupDialog(content::JAVASCRIPT_DIALOG_TYPE_ALERT);
  EXPECT_EQ(DismissalCause::kSubsequentDialogShown,
            tester.GetLastDismissalCause());
}

IN_PROC_BROWSER_TEST_F(JavaScriptDialogTest, NoDismissalAlertTabHidden) {
  JavaScriptDialogDismissalCauseTester tester(this);
  tester.PopupDialog(content::JAVASCRIPT_DIALOG_TYPE_ALERT);
  chrome::NewTab(browser());
  EXPECT_EQ(absl::nullopt, tester.GetLastDismissalCause());
}

IN_PROC_BROWSER_TEST_F(JavaScriptDialogTest, DismissalCauseUkm) {
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  GURL url = embedded_test_server()->GetURL("/title1.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  JavaScriptDialogDismissalCauseTester tester(this);
  tester.PopupDialog(content::JAVASCRIPT_DIALOG_TYPE_CONFIRM);
  tester.ClickDialogButton(true, std::u16string());

  auto entries = ukm_recorder.GetEntriesByName(
      ukm::builders::AbusiveExperienceHeuristic_JavaScriptDialog::kEntryName);
  EXPECT_EQ(1u, entries.size());
  ukm_recorder.ExpectEntrySourceHasUrl(entries.front(), url);
  ukm_recorder.ExpectEntryMetric(
      entries.front(),
      ukm::builders::AbusiveExperienceHeuristic_JavaScriptDialog::
          kDismissalCauseName,
      static_cast<int64_t>(DismissalCause::kDialogButtonClicked));
}

class JavaScriptDialogOriginTest
    : public JavaScriptDialogTest,
      public testing::WithParamInterface<const char*> {};

INSTANTIATE_TEST_SUITE_P(
    /* no prefix */,
    JavaScriptDialogOriginTest,
    ::testing::Values("data:text/html,

",
                      "javascript:undefined",
                      "about:blank"));

// Tests that the title for a dialog generated from a page with a non-HTTP URL
// that was spawned by an HTTP URL has that HTTP URL used for the title.
IN_PROC_BROWSER_TEST_P(JavaScriptDialogOriginTest, TitleForNonHTTPOrigin) {
  GURL url = embedded_test_server()->GetURL("a.com", "/title1.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Create a subframe.
  content::TestNavigationObserver nav_observer(tab);
  GURL test_url(GetParam());
  std::string script = content::JsReplace(R"(
      var iframe = document.createElement('iframe');
      iframe.src = $1;
      document.body.appendChild(iframe);)",
                                          test_url);
  ASSERT_TRUE(content::ExecJs(tab, script));
  if (!test_url.SchemeIs("javascript")) {
    // content::TestNavigationObserver times out if asked to wait for the
    // loading of a javascript: URL.
    nav_observer.Wait();
  }

  content::RenderFrameHost* subframe =
      content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0);
  ASSERT_TRUE(subframe);

  // Verify the title that would be used for a dialog spawned by that subframe.
  javascript_dialogs::AppModalDialogManager* dialog_manager =
      javascript_dialogs::AppModalDialogManager::GetInstance();
  EXPECT_EQ(base::UTF8ToUTF16(base::StringPrintf(
                "a.com:%d says", embedded_test_server()->port())),
            dialog_manager->GetTitle(tab, subframe->GetLastCommittedOrigin()));
}

class JavaScriptDialogForPrerenderTest : public JavaScriptDialogTest {
 public:
  JavaScriptDialogForPrerenderTest()
      : prerender_helper_(
            base::BindRepeating(&JavaScriptDialogForPrerenderTest::web_contents,
                                base::Unretained(this))) {}

  void SetUp() override {
    prerender_helper_.SetUp(embedded_test_server());
    JavaScriptDialogTest::SetUp();
  }

  void SetUpOnMainThread() override {
    web_contents_ = browser()->tab_strip_model()->GetActiveWebContents();
    JavaScriptDialogTest::SetUpOnMainThread();
  }

  content::WebContents* web_contents() { return web_contents_; }

 protected:
  raw_ptr<content::WebContents> web_contents_ = nullptr;
  content::test::PrerenderTestHelper prerender_helper_;
};

IN_PROC_BROWSER_TEST_F(JavaScriptDialogForPrerenderTest, NoDismissalDialog) {
  GURL url(embedded_test_server()->GetURL("/empty.html"));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  javascript_dialogs::TabModalDialogManager* js_helper =
      javascript_dialogs::TabModalDialogManager::FromWebContents(web_contents_);
  JavaScriptCallbackHelper callback_helper;
  bool did_suppress = false;

  GURL prerender_url = embedded_test_server()->GetURL("/title1.html");

  // Prerender to another site.
  prerender_helper_.AddPrerenderAsync(prerender_url);

  // Show an alert dialog
  js_helper->RunJavaScriptDialog(
      web_contents_, web_contents_->GetPrimaryMainFrame(),
      content::JAVASCRIPT_DIALOG_TYPE_ALERT, std::u16string(), std::u16string(),
      callback_helper.GetCallback(), &did_suppress);
  ASSERT_TRUE(js_helper->IsShowingDialogForTesting());

  prerender_helper_.WaitForPrerenderLoadCompletion(prerender_url);

  EXPECT_TRUE(js_helper->IsShowingDialogForTesting());

  // Navigate to the prerendered site.
  prerender_helper_.NavigatePrimaryPage(prerender_url);

  EXPECT_FALSE(js_helper->IsShowingDialogForTesting());
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<parent>
		<groupId>org.sonatype.oss</groupId>
		<artifactId>oss-parent</artifactId>
		<version>7</version>
	</parent>

	<groupId>com.github.ziplet</groupId>
	<artifactId>ziplet</artifactId>
	<version>2.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>
	<name>ziplet</name>
	<description>his filter can, based on HTTP headers in a HttpServletRequest, compress data written to the
		HttpServletResponse, or decompress data read from the request. When supported by the client browser,
		this can potentially greatly reduce the number of bytes written across the network from and to the client.
		As a Filter, this class can also be easily added to any J2EE 1.3+ web application.
	</description>
	<url>https://github.com/nbartels/pjl-comp-filter</url>
	<licenses>
		<license>
			<name>The Apache Software License, Version 2.0</name>
			<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
			<distribution>repo</distribution>
		</license>
	</licenses>
	<scm>
		<connection>scm:git:git@github.com:ziplet/ziplet.git</connection>
		<developerConnection>scm:git:git@github.com:ziplet/ziplet.git</developerConnection>
		<url>git@github.com:ziplet/ziplet.git</url>
	</scm>
	<developers>
		<developer>
			<id>fgaule</id>
			<name>Federico Gaule</name>
			<email>federico.gaule@gmail.com</email>
			<timezone>-3</timezone>
			<organization>Despegar</organization>
			<organizationUrl>http://www.despegar.com</organizationUrl>
		</developer>
		<developer>
			<id>fededonna</id>
			<name>Federico Donnarumma</name>
			<email>fdonnarumma@gmail.com</email>
			<timezone>-3</timezone>
			<organization>Despegar</organization>
			<organizationUrl>http://www.despegar.com</organizationUrl>
		</developer>
	</developers>

	<properties>
		<sl4j.version>1.7.6</sl4j.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${sl4j.version}</version>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${sl4j.version}</version>
		</dependency>

		<!--TEST-->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.8.1</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>com.mockrunner</groupId>
			<artifactId>mockrunner-servlet</artifactId>
			<version>1.0.0</version>
			<scope>test</scope>
		</dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
			<!-- Make a jar and put the sources in the jar -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-source-plugin</artifactId>
				<executions>
					<execution>
						<id>attach-sources</id>
						<phase>prepare-package</phase>
						<goals>
							<goal>jar-no-fork</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-javadoc-plugin</artifactId>
				<version>2.9.1</version>
				<configuration>
					<maxmemory>2048m</maxmemory>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>2.16</version>
				<dependencies>
					<dependency>
						<groupId>org.apache.maven.surefire</groupId>
						<artifactId>surefire-junit47</artifactId>
						<version>2.16</version>
					</dependency>
				</dependencies>
			</plugin>
			<plugin>
				<groupId>org.jasig.maven</groupId>
				<artifactId>maven-notice-plugin</artifactId>
				<version>1.0.5</version>
				<configuration>
					<noticeTemplate>src/main/resources/NOTICE.template</noticeTemplate>
					<licenseMapping>
						<param>src/main/resources/license-mappings.xml</param>
					</licenseMapping>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>


text:
package main

import (
	"bufio"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"os"
	"path/filepath"
	"regexp"
	"runtime"
	"strconv"
	"testing"
	"time"

	"github.com/Robpol86/githubBackup/api"
	"github.com/Robpol86/githubBackup/config"
	"github.com/Robpol86/githubBackup/testUtils"
	"github.com/stretchr/testify/require"
)

func TestVerifyDestValid(t *testing.T) {
	for _, mode := range []string{"dne", "empty", "warn"} {
		t.Run(mode, func(t *testing.T) {
			assert := require.New(t)

			// Tempdir.
			tmpdir, err := ioutil.TempDir("", "")
			assert.NoError(err)
			defer os.RemoveAll(tmpdir)

			// Prepare destination directory.
			dest := filepath.Join(tmpdir, "dest")
			if mode != "dne" {
				assert.NoError(os.Mkdir(dest, os.ModePerm))
			}
			if mode == "warn" {
				assert.NoError(os.Mkdir(filepath.Join(dest, "someDir"), os.ModePerm))
			}

			// Run.
			defer testUtils.ResetLogger()
			logs, stdout, stderr, err := testUtils.WithLogging(func() {
				assert.NoError(VerifyDest(dest, false))
			})

			// Verify logs.
			if mode != "warn" {
				assert.Empty(logs.Entries)
			} else {
				assert.NotEmpty(logs.Entries)
				assert.Equal("Prompting for enter key.", logs.LastEntry().Message)
			}

			// Verify streams.
			if mode == "warn" {
				assert.Contains(stdout, "Press Enter to continue...")
			} else {
				assert.Empty(stdout)
			}
			assert.Empty(stderr)

			// Verify directory exists.
			_, err = os.Stat(dest)
			assert.NoError(err)
		})
	}
}

func TestVerifyDestInvalid(t *testing.T) {
	for _, mode := range []string{"parent dne", "dest read only", "is file", "touch file ro"} {
		t.Run(mode, func(t *testing.T) {
			assert := require.New(t)

			// Tempdir.
			tmpdir, err := ioutil.TempDir("", "")
			assert.NoError(err)
			defer os.RemoveAll(tmpdir)

			// Prepare destination directory.
			dest := filepath.Join(tmpdir, "dest")
			var expected string
			switch mode {
			case "parent dne":
				dest = filepath.Join(dest, "dest")
				expected = "Failed creating directory: "
			case "dest read only":
				assert.NoError(os.Mkdir(dest, 0500))
				assert.NoError(setReadOnlyWindows(dest))
				expected = "Failed to touch file: "
			case "is file":
				handle, err := os.Create(dest)
				assert.NoError(err)
				handle.Close()
				expected = "Destination path exists but is not a directory."
			case "touch file ro":
				assert.NoError(os.Mkdir(dest, os.ModePerm))
				tfPath := filepath.Join(dest, touchFile)
				handle, err := os.Create(tfPath)
				assert.NoError(err)
				handle.Close()
				assert.NoError(os.Chmod(tfPath, 0400))
				assert.NoError(setReadOnlyWindows(tfPath))
				assert.NoError(os.Chmod(dest, 0500))
				assert.NoError(setReadOnlyWindows(dest))
				expected = "Failed to touch file: "
			}

			// Run.
			defer testUtils.ResetLogger()
			logs, _, stderr, err := testUtils.WithLogging(func() {
				assert.Error(VerifyDest(dest, false))
			})

			// Verify logs.
			assert.NotEmpty(logs.Entries)
			assert.Contains(logs.LastEntry().Message, expected)

			// Verify streams.
			assert.Empty(stderr)
		})
	}
}

func TestCollectFail(t *testing.T) {
	// Setup mock HTTP server.
	var failOn string
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if failOn == "repos" && r.URL.Path == "/user/repos" {
			w.Write([]byte("{':"))
		} else if failOn == "gists" && r.URL.Path == "/gists" {
			w.Write([]byte("{':"))
		} else {
			w.Write([]byte("[]"))
		}
	}))
	defer ts.Close()

	// Run tests.
	cfg := config.Config{}
	ghAPI := api.API{TestURL: ts.URL}
	ghRepos := api.GitHubRepos{}
	ghGists := api.GitHubGists{}
	for _, failOn = range []string{"repos", "gists", "empty"} {
		t.Run(failOn, func(t *testing.T) {
			assert := require.New(t)
			logs, stdout, stderr, err := testUtils.WithLogging(func() {
				assert.Error(Collect(&cfg, &ghAPI, &ghRepos, &ghGists))
			})
			assert.NoError(err)
			assert.Empty(stderr)
			assert.Empty(stdout)
			msg := logs.LastEntry().Message
			switch failOn {
			case "repos":
				assert.Contains(msg, "Querying GitHub API for repositories failed")
			case "gists":
				assert.Contains(msg, "Querying GitHub API for gists failed")
			default:
				assert.Equal("No repos or gists to backup. Nothing to do.", msg)
			}
		})
	}
}

func TestCollect(t *testing.T) {
	// Read JSON files into memory.
	assert := require.New(t)
	_, file, _, _ := runtime.Caller(0)
	replyRepos, err := ioutil.ReadFile(filepath.Join(filepath.Dir(file), "api", "repos_test.json"))
	assert.NoError(err)
	replyGists, err := ioutil.ReadFile(filepath.Join(filepath.Dir(file), "api", "gists_test.json"))
	assert.NoError(err)

	// Setup mock HTTP server.
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("X-RateLimit-Limit", "60")
		w.Header().Add("X-RateLimit-Remaining", "58")
		if r.URL.Path == "/user/repos" {
			w.Write(replyRepos)
		} else {
			w.Write(replyGists)
		}
	}))
	defer ts.Close()

	// Run test.
	cfg := config.Config{}
	ghAPI := api.API{TestURL: ts.URL}
	ghRepos := api.GitHubRepos{}
	ghGists := api.GitHubGists{}
	logs, stdout, stderr, err := testUtils.WithLogging(func() {
		assert.NoError(Collect(&cfg, &ghAPI, &ghRepos, &ghGists))
	})
	assert.NoError(err)
	assert.Empty(stderr)
	assert.Empty(stdout)

	// Verify logs.
	assert.Equal("Found 3 repos (1 private and 1 fork).", logs.Entries[4].Message)
	assert.Equal("--> 1 of them have wikis.", logs.Entries[5].Message)
	assert.Equal("--> 2 of them have GitHub Issues.", logs.Entries[6].Message)
	assert.Equal("Found 5 gists (3 private).", logs.Entries[7].Message)
	assert.Equal("--> 1 of them have comments.", logs.Entries[8].Message)
	assert.Equal(logs.Entries[8], logs.LastEntry())
}

func TestCollectRateLimit(t *testing.T) {
	// Read JSON file into memory.
	assert := require.New(t)
	_, file, _, _ := runtime.Caller(0)
	reply, err := ioutil.ReadFile(filepath.Join(filepath.Dir(file), "api", "repos_test.json"))
	assert.NoError(err)

	// Setup mock HTTP server.
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("X-RateLimit-Limit", "60")
		w.Header().Add("X-RateLimit-Remaining", "1")
		w.Header().Add("X-RateLimit-Reset", strconv.Itoa(int(time.Now().Unix()+120)))
		if r.URL.Path == "/user/repos" {
			w.Write(reply)
		} else {
			w.Write([]byte("[]"))
		}
	}))
	defer ts.Close()

	// Run test.
	cfg := config.Config{}
	ghAPI := api.API{TestURL: ts.URL}
	ghRepos := api.GitHubRepos{}
	ghGists := api.GitHubGists{}
	logs, stdout, stderr, err := testUtils.WithLogging(func() {
		assert.NoError(Collect(&cfg, &ghAPI, &ghRepos, &ghGists))
	})
	assert.NoError(err)
	assert.Empty(stderr)
	assert.Equal("Press Enter to continue...", stdout)

	// Verify logs.
	assert.Equal("Found 3 repos (1 private and 1 fork).", logs.Entries[4].Message)
	assert.Equal("--> 1 of them have wikis.", logs.Entries[5].Message)
	assert.Equal("--> 2 of them have GitHub Issues.", logs.Entries[6].Message)
	assert.Equal("Didn't find any GitHub Gists to backup.", logs.Entries[7].Message)
	assert.Equal("Only 1 API query of 60 remain. This may interrupt the program.", logs.Entries[8].Message)
	assert.Equal("GitHub will reset the counter in 2 minutes.", logs.Entries[9].Message)
}

func TestMainVersionConsistency(t *testing.T) {
	assert := require.New(t)

	// Open README file.
	handle, err := os.Open("README.rst")
	assert.NoError(err)
	defer handle.Close()

	// Collect first 10 changelog lines.
	var idx int
	var lines [10]string
	scanner := bufio.NewScanner(handle)
	for scanner.Scan() {
		line := scanner.Text()
		if idx == 0 && line != ".. changelog-section-start" {
			continue
		}
		lines[idx] = line
		idx++
		if idx >= len(lines) {
			break
		}
	}

	// Search for version.
	var readmeVersion string
	re := regexp.MustCompile(`^(\d+\.\d+\.\d+) - \d{4}-\d\d-\d\d$`)
	for _, line := range lines {
		found := re.FindStringSubmatch(line)
		if len(found) == 2 {
			readmeVersion = found[1]
		}
	}

	// Verify.
	assert.Equal(readmeVersion, config.Version)
}

func TestMainLogError(t *testing.T) {
	assert := require.New(t)

	tmpdir, err := ioutil.TempDir("", "")
	assert.NoError(err)
	defer os.RemoveAll(tmpdir)
	logFile := filepath.Join(tmpdir, "dne", "sample.log")

	defer testUtils.ResetLogger()
	stdout, stderr, err := testUtils.WithCapSys(func() {
		testUtils.ResetLogger()
		ret := Main([]string{"-l", logFile, tmpdir}, "")
		assert.Equal(2, ret)
	})

	assert.NoError(err)
	assert.Contains(stdout, "githubBackup "+config.Version)
	assert.Contains(stderr, "Failed to setup logging: ")
}

func TestMainBadDest(t *testing.T) {
	assert := require.New(t)

	tmpdir, err := ioutil.TempDir("", "")
	assert.NoError(err)
	defer os.RemoveAll(tmpdir)
	defer testUtils.ResetLogger()

	stdout, stderr, err := testUtils.WithCapSys(func() {
		testUtils.ResetLogger()
		ret := Main([]string{filepath.Join(tmpdir, "dne", "dest")}, "")
		assert.Equal(1, ret)
	})

	assert.NoError(err)
	assert.Contains(stdout, "githubBackup "+config.Version)
	assert.Contains(stderr, "Failed creating directory: ")
	if runtime.GOOS == "windows" {
		assert.Contains(stderr, "dest: The system cannot find the path specified.")
	} else {
		assert.Contains(stderr, "dest: no such file or directory")
	}
}

func TestMainTokenError(t *testing.T) {
	assert := require.New(t)

	tmpdir, err := ioutil.TempDir("", "")
	assert.NoError(err)
	defer os.RemoveAll(tmpdir)
	defer testUtils.ResetLogger()

	stdout, stderr, err := testUtils.WithCapSys(func() {
		testUtils.ResetLogger()
		ret := Main([]string{tmpdir}, "")
		assert.Equal(1, ret)
	})

	assert.NoError(err)
	assert.Contains(stdout, "githubBackup "+config.Version)
	assert.Contains(stderr, "Not querying GitHub API: ")
}

func TestMainReposGistsAPIError(t *testing.T) {
	assert := require.New(t)

	tmpdir, err := ioutil.TempDir("", "")
	assert.NoError(err)
	defer os.RemoveAll(tmpdir)
	defer testUtils.ResetLogger()

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("{':"))
	}))
	defer ts.Close()

	stdout, stderr, err := testUtils.WithCapSys(func() {
		testUtils.ResetLogger()
		ret := Main([]string{"-TuRobpol86", tmpdir}, ts.URL)
		assert.Equal(1, ret)
	})
	assert.NoError(err)
	assert.Contains(stdout, "githubBackup "+config.Version)
	assert.Contains(stderr, "Querying GitHub API for repositories failed")
}