text:
package dagger.internal.codegen.validation;

import static com.google.auto.common.MoreTypes.asDeclared;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.in;
import static com.google.common.collect.Collections2.transform;
import static dagger.internal.codegen.base.ComponentAnnotation.rootComponentAnnotation;
import static dagger.internal.codegen.base.DiagnosticFormatting.stripCommonTypePrefixes;
import static dagger.internal.codegen.base.Formatter.INDENT;
import static dagger.internal.codegen.base.Scopes.getReadableSource;
import static dagger.internal.codegen.base.Scopes.scopesOf;
import static dagger.internal.codegen.base.Scopes.singletonScope;
import static dagger.internal.codegen.base.Util.reentrantComputeIfAbsent;
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet;
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSetMultimap;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
import static javax.tools.Diagnostic.Kind.ERROR;

import com.google.auto.common.MoreElements;
import com.google.auto.common.MoreTypes;
import com.google.common.base.Equivalence.Wrapper;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets;
import dagger.internal.codegen.binding.ComponentCreatorDescriptor;
import dagger.internal.codegen.binding.ComponentDescriptor;
import dagger.internal.codegen.binding.ComponentRequirement;
import dagger.internal.codegen.binding.ComponentRequirement.NullPolicy;
import dagger.internal.codegen.binding.ContributionBinding;
import dagger.internal.codegen.binding.ErrorMessages;
import dagger.internal.codegen.binding.ErrorMessages.ComponentCreatorMessages;
import dagger.internal.codegen.binding.MethodSignatureFormatter;
import dagger.internal.codegen.binding.ModuleDescriptor;
import dagger.internal.codegen.compileroption.CompilerOptions;
import dagger.internal.codegen.compileroption.ValidationType;
import dagger.internal.codegen.kotlin.KotlinMetadataUtil;
import dagger.internal.codegen.langmodel.DaggerElements;
import dagger.internal.codegen.langmodel.DaggerTypes;
import dagger.spi.model.Scope;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Deque;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.StringJoiner;
import javax.inject.Inject;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic;

/**
 * Reports errors in the component hierarchy.
 *
 *

 *
Validates scope hierarchy of component dependencies and subcomponents.
 *
Reports errors if there are component dependency cycles.
 *
Reports errors if any abstract modules have non-abstract instance binding methods.
 *
Validates component creator types.
 *

 */
// TODO(dpb): Combine with ComponentHierarchyValidator.
public final class ComponentDescriptorValidator {

  private final DaggerElements elements;
  private final DaggerTypes types;
  private final CompilerOptions compilerOptions;
  private final MethodSignatureFormatter methodSignatureFormatter;
  private final ComponentHierarchyValidator componentHierarchyValidator;
  private final KotlinMetadataUtil metadataUtil;

  @Inject
  ComponentDescriptorValidator(
      DaggerElements elements,
      DaggerTypes types,
      CompilerOptions compilerOptions,
      MethodSignatureFormatter methodSignatureFormatter,
      ComponentHierarchyValidator componentHierarchyValidator,
      KotlinMetadataUtil metadataUtil) {
    this.elements = elements;
    this.types = types;
    this.compilerOptions = compilerOptions;
    this.methodSignatureFormatter = methodSignatureFormatter;
    this.componentHierarchyValidator = componentHierarchyValidator;
    this.metadataUtil = metadataUtil;
  }

  public ValidationReport validate(ComponentDescriptor component) {
    ComponentValidation validation = new ComponentValidation(component);
    validation.visitComponent(component);
    validation.report(component).addSubreport(componentHierarchyValidator.validate(component));
    return validation.buildReport();
  }

  private final class ComponentValidation {
    final ComponentDescriptor rootComponent;
    final Map<ComponentDescriptor, ValidationReport.Builder> reports = new LinkedHashMap<>();

    ComponentValidation(ComponentDescriptor rootComponent) {
      this.rootComponent = checkNotNull(rootComponent);
    }

    /** Returns a report that contains all validation messages found during traversal. */
    ValidationReport buildReport() {
      ValidationReport.Builder report = ValidationReport.about(rootComponent.typeElement());
      reports.values().forEach(subreport -> report.addSubreport(subreport.build()));
      return report.build();
    }

    /** Returns the report builder for a (sub)component. */
    private ValidationReport.Builder report(ComponentDescriptor component) {
      return reentrantComputeIfAbsent(
          reports, component, descriptor -> ValidationReport.about(descriptor.typeElement()));
    }

    private void reportComponentItem(
        Diagnostic.Kind kind, ComponentDescriptor component, String message) {
      report(component)
          .addItem(message, kind, component.typeElement(), component.annotation().annotation());
    }

    private void reportComponentError(ComponentDescriptor component, String error) {
      reportComponentItem(ERROR, component, error);
    }

    void visitComponent(ComponentDescriptor component) {
      validateDependencyScopes(component);
      validateComponentDependencyHierarchy(component);
      validateModules(component);
      validateCreators(component);
      component.childComponents().forEach(this::visitComponent);
    }

    /** Validates that component dependencies do not form a cycle. */
    private void validateComponentDependencyHierarchy(ComponentDescriptor component) {
      validateComponentDependencyHierarchy(component, component.typeElement(), new ArrayDeque<>());
    }

    /** Recursive method to validate that component dependencies do not form a cycle. */
    private void validateComponentDependencyHierarchy(
        ComponentDescriptor component, TypeElement dependency, Deque<TypeElement> dependencyStack) {
      if (dependencyStack.contains(dependency)) {
        // Current component has already appeared in the component chain.
        StringBuilder message = new StringBuilder();
        message.append(component.typeElement().getQualifiedName());
        message.append(" contains a cycle in its component dependencies:\n");
        dependencyStack.push(dependency);
        appendIndentedComponentsList(message, dependencyStack);
        dependencyStack.pop();
        reportComponentItem(
            compilerOptions.scopeCycleValidationType().diagnosticKind().get(),
            component,
            message.toString());
      } else if (compilerOptions.validateTransitiveComponentDependencies()
          // Always validate direct component dependencies referenced by this component regardless
          // of the flag value
          || dependencyStack.isEmpty()) {
        rootComponentAnnotation(dependency)
            .ifPresent(
                componentAnnotation -> {
                  dependencyStack.push(dependency);

                  for (TypeElement nextDependency : componentAnnotation.dependencies()) {
                    validateComponentDependencyHierarchy(
                        component, nextDependency, dependencyStack);
                  }

                  dependencyStack.pop();
                });
      }
    }

    /**
     * Validates that among the dependencies there are no cycles within the scoping chain, and that
     * singleton components have no scoped dependencies.
     */
    private void validateDependencyScopes(ComponentDescriptor component) {
      ImmutableSet<Scope> scopes = component.scopes();
      ImmutableSet<TypeElement> scopedDependencies =
          scopedTypesIn(
              component
                  .dependencies()
                  .stream()
                  .map(ComponentRequirement::typeElement)
                  .collect(toImmutableSet()));
      if (!scopes.isEmpty()) {
        Scope singletonScope = singletonScope(elements);
        // Dagger 1.x scope compatibility requires this be suppress-able.
        if (compilerOptions.scopeCycleValidationType().diagnosticKind().isPresent()
            && scopes.contains(singletonScope)) {
          // Singleton is a special-case representing the longest lifetime, and therefore
          // @Singleton components may not depend on scoped components
          if (!scopedDependencies.isEmpty()) {
            StringBuilder message =
                new StringBuilder(
                    "This @Singleton component cannot depend on scoped components:\n");
            appendIndentedComponentsList(message, scopedDependencies);
            reportComponentItem(
                compilerOptions.scopeCycleValidationType().diagnosticKind().get(),
                component,
                message.toString());
          }
        } else {
          // Dagger 1.x scope compatibility requires this be suppress-able.
          if (!compilerOptions.scopeCycleValidationType().equals(ValidationType.NONE)) {
            validateDependencyScopeHierarchy(
                component, component.typeElement(), new ArrayDeque<>(), new ArrayDeque<>());
          }
        }
      } else {
        // Scopeless components may not depend on scoped components.
        if (!scopedDependencies.isEmpty()) {
          StringBuilder message =
              new StringBuilder(component.typeElement().getQualifiedName())
                  .append(" (unscoped) cannot depend on scoped components:\n");
          appendIndentedComponentsList(message, scopedDependencies);
          reportComponentError(component, message.toString());
        }
      }
    }

    private void validateModules(ComponentDescriptor component) {
      for (ModuleDescriptor module : component.modules()) {
        if (module.moduleElement().getModifiers().contains(Modifier.ABSTRACT)) {
          for (ContributionBinding binding : module.bindings()) {
            if (binding.requiresModuleInstance()) {
              report(component).addError(abstractModuleHasInstanceBindingMethodsError(module));
              break;
            }
          }
        }
      }
    }

    private String abstractModuleHasInstanceBindingMethodsError(ModuleDescriptor module) {
      String methodAnnotations;
      switch (module.kind()) {
        case MODULE:
          methodAnnotations = "@Provides";
          break;
        case PRODUCER_MODULE:
          methodAnnotations = "@Provides or @Produces";
          break;
        default:
          throw new AssertionError(module.kind());
      }
      return String.format(
          "%s is abstract and has instance %s methods. Consider making the methods static or "
              + "including a non-abstract subclass of the module instead.",
          module.moduleElement(), methodAnnotations);
    }

    private void validateCreators(ComponentDescriptor component) {
      if (!component.creatorDescriptor().isPresent()) {
        // If no builder, nothing to validate.
        return;
      }

      ComponentCreatorDescriptor creator = component.creatorDescriptor().get();
      ComponentCreatorMessages messages = ErrorMessages.creatorMessagesFor(creator.annotation());

      // Requirements for modules and dependencies that the creator can set
      Set<ComponentRequirement> creatorModuleAndDependencyRequirements =
          creator.moduleAndDependencyRequirements();
      // Modules and dependencies the component requires
      Set<ComponentRequirement> componentModuleAndDependencyRequirements =
          component.dependenciesAndConcreteModules();

      // Requirements that the creator can set that don't match any requirements that the component
      // actually has.
      Set<ComponentRequirement> inapplicableRequirementsOnCreator =
          Sets.difference(
              creatorModuleAndDependencyRequirements, componentModuleAndDependencyRequirements);

      DeclaredType container = asDeclared(creator.typeElement().asType());
      if (!inapplicableRequirementsOnCreator.isEmpty()) {
        Collection<Element> excessElements =
            Multimaps.filterKeys(
                    creator.unvalidatedRequirementElements(), in(inapplicableRequirementsOnCreator))
                .values();
        String formatted =
            excessElements.stream()
                .map(element -> formatElement(element, container))
                .collect(joining(", ", "[", "]"));
        report(component)
            .addError(String.format(messages.extraSetters(), formatted), creator.typeElement());
      }

      // Component requirements that the creator must be able to set
      Set<ComponentRequirement> mustBePassed =
          Sets.filter(
              componentModuleAndDependencyRequirements,
              input -> input.nullPolicy(elements, metadataUtil).equals(NullPolicy.THROW));
      // Component requirements that the creator must be able to set, but can't
      Set<ComponentRequirement> missingRequirements =
          Sets.difference(mustBePassed, creatorModuleAndDependencyRequirements);

      if (!missingRequirements.isEmpty()) {
        report(component)
            .addError(
                String.format(
                    messages.missingSetters(),
                    missingRequirements.stream().map(ComponentRequirement::type).collect(toList())),
                creator.typeElement());
      }

      // Validate that declared creator requirements (modules, dependencies) have unique types.
      ImmutableSetMultimap<Wrapper<TypeMirror>, Element> declaredRequirementsByType =
          Multimaps.filterKeys(
                  creator.unvalidatedRequirementElements(),
                  creatorModuleAndDependencyRequirements::contains)
              .entries().stream()
              .collect(
                  toImmutableSetMultimap(entry -> entry.getKey().wrappedType(), Entry::getValue));
      declaredRequirementsByType
          .asMap()
          .forEach(
              (typeWrapper, elementsForType) -> {
                if (elementsForType.size() > 1) {
                  TypeMirror type = typeWrapper.get();
                  // TODO(cgdecker): Attach this error message to the factory method rather than
                  // the component type if the elements are factory method parameters AND the
                  // factory method is defined by the factory type itself and not by a supertype.
                  report(component)
                      .addError(
                          String.format(
                              messages.multipleSettersForModuleOrDependencyType(),
                              type,
                              transform(
                                  elementsForType, element -> formatElement(element, container))),
                          creator.typeElement());
                }
              });

      // TODO(cgdecker): Duplicate binding validation should handle the case of multiple elements
      // that set the same bound-instance Key, but validating that here would make it fail faster
      // for subcomponents.
    }

    private String formatElement(Element element, DeclaredType container) {
      // TODO(cgdecker): Extract some or all of this to another class?
      // But note that it does different formatting for parameters than
      // DaggerElements.elementToString(Element).
      switch (element.getKind()) {
        case METHOD:
          return methodSignatureFormatter.format(
              MoreElements.asExecutable(element), Optional.of(container));
        case PARAMETER:
          return formatParameter(MoreElements.asVariable(element), container);
        default:
          // This method shouldn't be called with any other type of element.
          throw new AssertionError();
      }
    }

    private String formatParameter(VariableElement parameter, DeclaredType container) {
      // TODO(cgdecker): Possibly leave the type (and annotations?) off of the parameters here and
      // just use their names, since the type will be redundant in the context of the error message.
      StringJoiner joiner = new StringJoiner(" ");
      parameter.getAnnotationMirrors().stream().map(Object::toString).forEach(joiner::add);
      TypeMirror parameterType = resolveParameterType(parameter, container);
      return joiner
          .add(stripCommonTypePrefixes(parameterType.toString()))
          .add(parameter.getSimpleName())
          .toString();
    }

    private TypeMirror resolveParameterType(VariableElement parameter, DeclaredType container) {
      ExecutableElement method =
          MoreElements.asExecutable(parameter.getEnclosingElement());
      int parameterIndex = method.getParameters().indexOf(parameter);

      ExecutableType methodType = MoreTypes.asExecutable(types.asMemberOf(container, method));
      return methodType.getParameterTypes().get(parameterIndex);
    }

    /**
     * Validates that scopes do not participate in a scoping cycle - that is to say, scoped
     * components are in a hierarchical relationship terminating with Singleton.
     *
     *
As a side-effect, this means scoped components cannot have a dependency cycle between
     * themselves, since a component's presence within its own dependency path implies a cyclical
     * relationship between scopes. However, cycles in component dependencies are explicitly checked
     * in {@link #validateComponentDependencyHierarchy(ComponentDescriptor)}.
     */
    private void validateDependencyScopeHierarchy(
        ComponentDescriptor component,
        TypeElement dependency,
        Deque<ImmutableSet<Scope>> scopeStack,
        Deque<TypeElement> scopedDependencyStack) {
      ImmutableSet<Scope> scopes = scopesOf(dependency);
      if (stackOverlaps(scopeStack, scopes)) {
        scopedDependencyStack.push(dependency);
        // Current scope has already appeared in the component chain.
        StringBuilder message = new StringBuilder();
        message.append(component.typeElement().getQualifiedName());
        message.append(" depends on scoped components in a non-hierarchical scope ordering:\n");
        appendIndentedComponentsList(message, scopedDependencyStack);
        if (compilerOptions.scopeCycleValidationType().diagnosticKind().isPresent()) {
          reportComponentItem(
              compilerOptions.scopeCycleValidationType().diagnosticKind().get(),
              component,
              message.toString());
        }
        scopedDependencyStack.pop();
      } else if (compilerOptions.validateTransitiveComponentDependencies()
          // Always validate direct component dependencies referenced by this component regardless
          // of the flag value
          || scopedDependencyStack.isEmpty()) {
        // TODO(beder): transitively check scopes of production components too.
        rootComponentAnnotation(dependency)
            .filter(componentAnnotation -> !componentAnnotation.isProduction())
            .ifPresent(
                componentAnnotation -> {
                  ImmutableSet<TypeElement> scopedDependencies =
                      scopedTypesIn(componentAnnotation.dependencies());
                  if (!scopedDependencies.isEmpty()) {
                    // empty can be ignored (base-case)
                    scopeStack.push(scopes);
                    scopedDependencyStack.push(dependency);
                    for (TypeElement scopedDependency : scopedDependencies) {
                      validateDependencyScopeHierarchy(
                          component,
                          scopedDependency,
                          scopeStack,
                          scopedDependencyStack);
                    }
                    scopedDependencyStack.pop();
                    scopeStack.pop();
                  }
                }); // else: we skip component dependencies which are not components
      }
    }

    private <T> boolean stackOverlaps(Deque<ImmutableSet<T>> stack, ImmutableSet<T> set) {
      for (ImmutableSet<T> entry : stack) {
        if (!Sets.intersection(entry, set).isEmpty()) {
          return true;
        }
      }
      return false;
    }

    /** Appends and formats a list of indented component types (with their scope annotations). */
    private void appendIndentedComponentsList(StringBuilder message, Iterable<TypeElement> types) {
      for (TypeElement scopedComponent : types) {
        message.append(INDENT);
        for (Scope scope : scopesOf(scopedComponent)) {
          message.append(getReadableSource(scope)).append(' ');
        }
        message
            .append(stripCommonTypePrefixes(scopedComponent.getQualifiedName().toString()))
            .append('\n');
      }
    }

    /**
     * Returns a set of type elements containing only those found in the input set that have a
     * scoping annotation.
     */
    private ImmutableSet<TypeElement> scopedTypesIn(Collection<TypeElement> types) {
      return types.stream().filter(type -> !scopesOf(type).isEmpty()).collect(toImmutableSet());
    }
  }
}


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

'use strict';

var path = require('path'),
    url = require('url'),
    util = require('util');

var promise = require('../').promise,
    httpUtil = require('../http/util'),
    exec = require('../io/exec'),
    net = require('../net'),
    portprober = require('../net/portprober');

/**
 * Configuration options for a DriverService instance.
 *

 *

 *
{@code loopback} - Whether the service should only be accessed on this
 *     host's loopback address.
 *
{@code port} - The port to start the server on (must be > 0). If the
 *     port is provided as a promise, the service will wait for the promise to
 *     resolve before starting.
 *
{@code args} - The arguments to pass to the service. If a promise is
 *     provided, the service will wait for it to resolve before starting.
 *
{@code path} - The base path on the server for the WebDriver wire
 *     protocol (e.g. '/wd/hub'). Defaults to '/'.
 *
{@code env} - The environment variables that should be visible to the
 *     server process. Defaults to inheriting the current process's
 *     environment.
 *
{@code stdio} - IO configuration for the spawned server process. For
 *     more information, refer to the documentation of
 *     {@code child_process.spawn}.
 *

 *
 * @typedef {{
 *   port: (number|!webdriver.promise.Promise.<number>),
 *   args: !(Array.<string>|webdriver.promise.Promise.<!Array.<string>>),
 *   path: (string|undefined),
 *   env: (!Object.<string, string>|undefined),
 *   stdio: (string|!Array.<string|number|!Stream|null|undefined>|undefined)
 * }}
 */
var ServiceOptions;

/**
 * Manages the life and death of a native executable WebDriver server.
 *
 *
It is expected that the driver server implements the
 * WebDriver
 * Wire Protocol. Furthermore, the managed server should support multiple
 * concurrent sessions, so that this class may be reused for multiple clients.
 *
 * @param {string} executable Path to the executable to run.
 * @param {!ServiceOptions} options Configuration options for the service.
 * @constructor
 */
function DriverService(executable, options) {

  /** @private {string} */
  this.executable_ = executable;

  /** @private {boolean} */
  this.loopbackOnly_ = !!options.loopback;

  /** @private {(number|!webdriver.promise.Promise.<number>)} */
  this.port_ = options.port;

  /**
   * @private {!(Array.<string>|webdriver.promise.Promise.<!Array.<string>>)}
   */
  this.args_ = options.args;

  /** @private {string} */
  this.path_ = options.path || '/';

  /** @private {!Object.<string, string>} */
  this.env_ = options.env || process.env;

  /** @private {(string|!Array.<string|number|!Stream|null|undefined>)} */
  this.stdio_ = options.stdio || 'ignore';

  /**
   * A promise for the managed subprocess, or null if the server has not been
   * started yet. This promise will never be rejected.
   * @private {promise.Promise.<!exec.Command>}
   */
  this.command_ = null;

  /**
   * Promise that resolves to the server's address or null if the server has
   * not been started. This promise will be rejected if the server terminates
   * before it starts accepting WebDriver requests.
   * @private {promise.Promise.<string>}
   */
  this.address_ = null;
}

/**
 * The default amount of time, in milliseconds, to wait for the server to
 * start.
 * @type {number}
 */
DriverService.DEFAULT_START_TIMEOUT_MS = 30 * 1000;

/**
 * @return {!webdriver.promise.Promise.<string>} A promise that resolves to
 *    the server's address.
 * @throws {Error} If the server has not been started.
 */
DriverService.prototype.address = function() {
  if (this.address_) {
    return this.address_;
  }
  throw Error('Server has not been started.');
};

/**
 * Returns whether the underlying process is still running. This does not take
 * into account whether the process is in the process of shutting down.
 * @return {boolean} Whether the underlying service process is running.
 */
DriverService.prototype.isRunning = function() {
  return !!this.address_;
};

/**
 * Starts the server if it is not already running.
 * @param {number=} opt_timeoutMs How long to wait, in milliseconds, for the
 *     server to start accepting requests. Defaults to 30 seconds.
 * @return {!promise.Promise.<string>} A promise that will resolve
 *     to the server's base URL when it has started accepting requests. If the
 *     timeout expires before the server has started, the promise will be
 *     rejected.
 */
DriverService.prototype.start = function(opt_timeoutMs) {
  if (this.address_) {
    return this.address_;
  }

  var timeout = opt_timeoutMs || DriverService.DEFAULT_START_TIMEOUT_MS;

  var self = this;
  this.command_ = promise.defer();
  this.address_ = promise.defer();
  this.address_.fulfill(promise.when(this.port_, function(port) {
    if (port <= 0) {
      throw Error('Port must be > 0: ' + port);
    }
    return promise.when(self.args_, function(args) {
      var command = exec(self.executable_, {
        args: args,
        env: self.env_,
        stdio: self.stdio_
      });

      self.command_.fulfill(command);

      command.result().then(function(result) {
        self.address_.reject(result.code == null ?
            Error('Server was killed with ' + result.signal) :
            Error('Server exited with ' + result.code));
        self.address_ = null;
        self.command_ = null;
      });

      var serverUrl = url.format({
        protocol: 'http',
        hostname: !self.loopbackOnly_ && net.getAddress() ||
            net.getLoopbackAddress(),
        port: port,
        pathname: self.path_
      });

      return httpUtil.waitForServer(serverUrl, timeout).then(function() {
        return serverUrl;
      });
    });
  }));

  return this.address_;
};

/**
 * Stops the service if it is not currently running. This function will kill
 * the server immediately. To synchronize with the active control flow, use
 * {@link #stop()}.
 * @return {!webdriver.promise.Promise} A promise that will be resolved when
 *     the server has been stopped.
 */
DriverService.prototype.kill = function() {
  if (!this.address_ || !this.command_) {
    return promise.fulfilled();  // Not currently running.
  }
  return this.command_.then(function(command) {
    command.kill('SIGTERM');
  });
};

/**
 * Schedules a task in the current control flow to stop the server if it is
 * currently running.
 * @return {!webdriver.promise.Promise} A promise that will be resolved when
 *     the server has been stopped.
 */
DriverService.prototype.stop = function() {
  return promise.controlFlow().execute(this.kill.bind(this));
};

/**
 * Manages the life and death of the
 *
 * standalone Selenium server.
 *
 * @param {string} jar Path to the Selenium server jar.
 * @param {SeleniumServer.Options=} opt_options Configuration options for the
 *     server.
 * @throws {Error} If the path to the Selenium jar is not specified or if an
 *     invalid port is specified.
 * @constructor
 * @extends {DriverService}
 */
function SeleniumServer(jar, opt_options) {
  if (!jar) {
    throw Error('Path to the Selenium jar not specified');
  }

  var options = opt_options || {};

  if (options.port < 0) {
    throw Error('Port must be >= 0: ' + options.port);
  }

  var port = options.port || portprober.findFreePort();
  var args = promise.when(options.jvmArgs || [], function(jvmArgs) {
    return promise.when(options.args || [], function(args) {
      return promise.when(port, function(port) {
        return jvmArgs.concat(['-jar', jar, '-port', port]).concat(args);
      });
    });
  });

  DriverService.call(this, 'java', {
    port: port,
    args: args,
    path: '/wd/hub',
    env: options.env,
    stdio: options.stdio
  });
}
util.inherits(SeleniumServer, DriverService);

/**
 * Options for the Selenium server:
 *

 *
{@code port} - The port to start the server on (must be > 0). If the
 *     port is provided as a promise, the service will wait for the promise to
 *     resolve before starting.
 *
{@code args} - The arguments to pass to the service. If a promise is
 *     provided, the service will wait for it to resolve before starting.
 *
{@code jvmArgs} - The arguments to pass to the JVM. If a promise is
 *     provided, the service will wait for it to resolve before starting.
 *
{@code env} - The environment variables that should be visible to the
 *     server process. Defaults to inheriting the current process's
 *     environment.
 *
{@code stdio} - IO configuration for the spawned server process. For
 *     more information, refer to the documentation of
 *     {@code child_process.spawn}.
 *

 *
 * @typedef {{
 *   port: (number|!webdriver.promise.Promise.<number>),
 *   args: !(Array.<string>|webdriver.promise.Promise.<!Array.<string>>),
 *   jvmArgs: (!Array.<string>|
 *             !webdriver.promise.Promise.<!Array.<string>>|
 *             undefined),
 *   env: (!Object.<string, string>|undefined),
 *   stdio: (string|!Array.<string|number|!Stream|null|undefined>|undefined)
 * }}
 */
SeleniumServer.Options;

// PUBLIC API

exports.DriverService = DriverService;
exports.SeleniumServer = SeleniumServer;

redpajama_set_name: RedPajamaGithub


text:
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.ComponentModel;
using System.Security.Cryptography;

namespace Azure.Security.KeyVault.Keys
{
    /// <summary>
    /// Elliptic Curve Cryptography (ECC) curve names.
    /// </summary>
    public readonly struct KeyCurveName : IEquatable<KeyCurveName>
    {
        private const string P256Value = "P-256";
        private const string P256KValue = "P-256K";
        private const string P384Value = "P-384";
        private const string P521Value = "P-521";

        private const string P256OidValue = "1.2.840.10045.3.1.7";
        private const string P256KOidValue = "1.3.132.0.10";
        private const string P384OidValue = "1.3.132.0.34";
        private const string P521OidValue = "1.3.132.0.35";

        private readonly string _value;

        /// <summary>
        /// Initializes a new instance of the <see cref="KeyCurveName"/> structure.
        /// </summary>
        /// <param name="value">The string value of the instance.</param>
        public KeyCurveName(string value)
        {
            _value = value ?? throw new ArgumentNullException(nameof(value));
        }

        /// <summary>
        /// Gets the NIST P-256 elliptic curve, AKA SECG curve SECP256R1
        /// For more information, see <see href="https://docs.microsoft.com/azure/key-vault/keys/about-keys#curve-types">Curve types</see>.
        /// </summary>
        public static KeyCurveName P256 { get; } = new KeyCurveName(P256Value);

        /// <summary>
        /// Gets the SECG SECP256K1 elliptic curve.
        /// For more information, see <see href="https://docs.microsoft.com/azure/key-vault/keys/about-keys#curve-types">Curve types</see>.
        /// </summary>
        public static KeyCurveName P256K { get; } = new KeyCurveName(P256KValue);

        /// <summary>
        /// Gets the NIST P-384 elliptic curve, AKA SECG curve SECP384R1.
        /// For more information, see <see href="https://docs.microsoft.com/azure/key-vault/keys/about-keys#curve-types">Curve types</see>.
        /// </summary>
        public static KeyCurveName P384 { get; } = new KeyCurveName(P384Value);

        /// <summary>
        /// Gets the NIST P-521 elliptic curve, AKA SECG curve SECP521R1.
        /// For more information, see <see href="https://docs.microsoft.com/azure/key-vault/keys/about-keys#curve-types">Curve types</see>.
        /// </summary>
        public static KeyCurveName P521 { get; } = new KeyCurveName(P521Value);

        /// <summary>
        /// Determines if two <see cref="KeyCurveName"/> values are the same.
        /// </summary>
        /// <param name="left">The first <see cref="KeyCurveName"/> to compare.</param>
        /// <param name="right">The second <see cref="KeyCurveName"/> to compare.</param>
        /// <returns>True if <paramref name="left"/> and <paramref name="right"/> are the same; otherwise, false.</returns>
        public static bool operator ==(KeyCurveName left, KeyCurveName right) => left.Equals(right);

        /// <summary>
        /// Determines if two <see cref="KeyCurveName"/> values are different.
        /// </summary>
        /// <param name="left">The first <see cref="KeyCurveName"/> to compare.</param>
        /// <param name="right">The second <see cref="KeyCurveName"/> to compare.</param>
        /// <returns>True if <paramref name="left"/> and <paramref name="right"/> are different; otherwise, false.</returns>
        public static bool operator !=(KeyCurveName left, KeyCurveName right) => !left.Equals(right);

        /// <summary>
        /// Converts a string to a <see cref="KeyCurveName"/>.
        /// </summary>
        /// <param name="value">The string value to convert.</param>
        public static implicit operator KeyCurveName(string value) => new KeyCurveName(value);

        /// <inheritdoc/>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override bool Equals(object obj) => obj is KeyCurveName other && Equals(other);

        /// <inheritdoc/>
        public bool Equals(KeyCurveName other) => string.Equals(_value, other._value, StringComparison.Ordinal);

        /// <inheritdoc/>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override int GetHashCode() => _value?.GetHashCode() ?? 0;

        /// <inheritdoc/>
        public override string ToString() => _value;

        internal static KeyCurveName FromOid(Oid oid, int keySize = 0)
        {
            if (!string.IsNullOrEmpty(oid?.Value))
            {
                if (string.Equals(oid.Value, P521OidValue, StringComparison.Ordinal))
                {
                    return P521;
                }

                if (string.Equals(oid.Value, P384OidValue, StringComparison.Ordinal))
                {
                    return P384;
                }

                if (string.Equals(oid.Value, P256KOidValue, StringComparison.Ordinal))
                {
                    return P256K;
                }

                if (string.Equals(oid.Value, P256OidValue, StringComparison.Ordinal))
                {
                    return P256;
                }
            }

            if (!string.IsNullOrEmpty(oid?.FriendlyName))
            {
                switch (keySize)
                {
                    case 521 when string.Equals(oid.FriendlyName, "nistP521", StringComparison.OrdinalIgnoreCase)
                               || string.Equals(oid.FriendlyName, "secp521r1", StringComparison.OrdinalIgnoreCase)
                               || string.Equals(oid.FriendlyName, "ECDSA_P521", StringComparison.OrdinalIgnoreCase):
                        return P521;

                    case 384 when string.Equals(oid.FriendlyName, "nistP384", StringComparison.OrdinalIgnoreCase)
                               || string.Equals(oid.FriendlyName, "secp384r1", StringComparison.OrdinalIgnoreCase)
                               || string.Equals(oid.FriendlyName, "ECDSA_P384", StringComparison.OrdinalIgnoreCase):
                        return P384;

                    case 256 when string.Equals(oid.FriendlyName, "secp256k1", StringComparison.OrdinalIgnoreCase):
                        return P256K;

                    case 256 when string.Equals(oid.FriendlyName, "nistP256", StringComparison.OrdinalIgnoreCase)
                               || string.Equals(oid.FriendlyName, "secp256r1", StringComparison.OrdinalIgnoreCase)
                               || string.Equals(oid.FriendlyName, "ECDSA_P256", StringComparison.OrdinalIgnoreCase):
                        return P256;
                }
            }

            return default;
        }

        internal bool IsSupported
        {
            get
            {
                switch (_value)
                {
                    case P256Value:
                    case P256KValue:
                    case P384Value:
                    case P521Value:
                        return true;

                    default:
                        return false;
                }
            }
        }

        internal int KeyParameterSize => _value switch
        {
            P256Value => 32,
            P256KValue => 32,
            P384Value => 48,
            P521Value => 66,
            _ => 0,
        };
        internal int KeySize => _value switch
        {
            P256Value => 256,
            P256KValue => 256,
            P384Value => 384,
            P521Value => 521,
            _ => 0,
        };

        internal Oid Oid => _value switch
        {
            P256Value => new Oid(P256OidValue),
            P256KValue => new Oid(P256KOidValue),
            P384Value => new Oid(P384OidValue),
            P521Value => new Oid(P521OidValue),
            _ => null,
        };
    }
}


text:
Les fonctions en JavaScript sont des objets de première classe. Cela signifie qu'elles peuvent être passées comme toute autre valeur. Une utilisation courante de cette caractéristique est de passer une *fonction anonyme* comme une fonction de rappel "callback" qui peut être asynchrone.

### La déclaration `function`

    function foo() {}

La fonction ci-dessus est [hissée](#function.scopes) "hoisted" avant le démarrage du programme; ainsi, elle est donc disponible partout dans la portée "scope" d'application où la fonction a été définie, même si appelé avant sa définition dans le code source.

    foo(); // Fonctionne car foo a été crée avant l'exécution de ce code
    function foo() {}

### L'expresssion `function`

    var foo = function() {};

Cet exemple attribue une fonction *anonyme* et sans nom à la variable `foo`.

    foo; // 'undefined'
    foo(); // provoque un erreur de type TypeError
    var foo = function() {};

En raison du fait que `var` est une déclaration qui hisse le nom de la variable `foo` avant que l'exécution réelle du code ne commence, `foo` est déjà déclarée lorsque le script est exécuté.

Mais comme les assignements ne se produisent qu'au moment de l'exécution, la valeur de `foo` sera par défaut mise à [undefined](#core.undefined) avant l'exécution du code.

### L'expression de fonction nommée

Un autre cas est l'attribution de fonctions nommées.

    var foo = function bar() {
        bar(); // Works
    }
    bar(); // erreur de reference ReferenceError

Ici, `bar` n'est pas disponible dans la portée externe "outer scope", puisque la fonction est seulement assignée à `foo`, mais elle est disponible à l'intérieur de `bar`. Cela est dû à la méthode de [résolution de noms](#function.scopes) de JavaScript: le nom de la fonction est *toujours* disponible dans la portée locale "local scope" de la fonction elle-même.


text:
from typing import (
    Any,
    AsyncIterator,
    Awaitable,
    Callable,
    Sequence,
    Tuple,
    Optional,
    Iterator,
)

from google.cloud.dialogflow_v2beta1.types import intent

class ListIntentsPager:
    """A pager for iterating through ``list_intents`` requests.

    This class thinly wraps an initial
    :class:`google.cloud.dialogflow_v2beta1.types.ListIntentsResponse` object, and
    provides an ``__iter__`` method to iterate through its
    ``intents`` field.

    If there are more pages, the ``__iter__`` method will make additional
    ``ListIntents`` requests and continue to iterate
    through the ``intents`` field on the
    corresponding responses.

    All the usual :class:`google.cloud.dialogflow_v2beta1.types.ListIntentsResponse`
    attributes are available on the pager. If multiple requests are made, only
    the most recent response is retained, and thus used for attribute lookup.
    """

    def __init__(
        self,
        method: Callable[..., intent.ListIntentsResponse],
        request: intent.ListIntentsRequest,
        response: intent.ListIntentsResponse,
        *,
        metadata: Sequence[Tuple[str, str]] = ()
    ):
        """Instantiate the pager.

        Args:
            method (Callable): The method that was originally called, and
                which instantiated this pager.
            request (google.cloud.dialogflow_v2beta1.types.ListIntentsRequest):
                The initial request object.
            response (google.cloud.dialogflow_v2beta1.types.ListIntentsResponse):
                The initial response object.
            metadata (Sequence[Tuple[str, str]]): Strings which should be
                sent along with the request as metadata.
        """
        self._method = method
        self._request = intent.ListIntentsRequest(request)
        self._response = response
        self._metadata = metadata

    def __getattr__(self, name: str) -> Any:
        return getattr(self._response, name)

    @property
    def pages(self) -> Iterator[intent.ListIntentsResponse]:
        yield self._response
        while self._response.next_page_token:
            self._request.page_token = self._response.next_page_token
            self._response = self._method(self._request, metadata=self._metadata)
            yield self._response

    def __iter__(self) -> Iterator[intent.Intent]:
        for page in self.pages:
            yield from page.intents

    def __repr__(self) -> str:
        return "{0}<{1!r}>".format(self.__class__.__name__, self._response)

class ListIntentsAsyncPager:
    """A pager for iterating through ``list_intents`` requests.

    This class thinly wraps an initial
    :class:`google.cloud.dialogflow_v2beta1.types.ListIntentsResponse` object, and
    provides an ``__aiter__`` method to iterate through its
    ``intents`` field.

    If there are more pages, the ``__aiter__`` method will make additional
    ``ListIntents`` requests and continue to iterate
    through the ``intents`` field on the
    corresponding responses.

    All the usual :class:`google.cloud.dialogflow_v2beta1.types.ListIntentsResponse`
    attributes are available on the pager. If multiple requests are made, only
    the most recent response is retained, and thus used for attribute lookup.
    """

    def __init__(
        self,
        method: Callable[..., Awaitable[intent.ListIntentsResponse]],
        request: intent.ListIntentsRequest,
        response: intent.ListIntentsResponse,
        *,
        metadata: Sequence[Tuple[str, str]] = ()
    ):
        """Instantiates the pager.

        Args:
            method (Callable): The method that was originally called, and
                which instantiated this pager.
            request (google.cloud.dialogflow_v2beta1.types.ListIntentsRequest):
                The initial request object.
            response (google.cloud.dialogflow_v2beta1.types.ListIntentsResponse):
                The initial response object.
            metadata (Sequence[Tuple[str, str]]): Strings which should be
                sent along with the request as metadata.
        """
        self._method = method
        self._request = intent.ListIntentsRequest(request)
        self._response = response
        self._metadata = metadata

    def __getattr__(self, name: str) -> Any:
        return getattr(self._response, name)

    @property
    async def pages(self) -> AsyncIterator[intent.ListIntentsResponse]:
        yield self._response
        while self._response.next_page_token:
            self._request.page_token = self._response.next_page_token
            self._response = await self._method(self._request, metadata=self._metadata)
            yield self._response

    def __aiter__(self) -> AsyncIterator[intent.Intent]:
        async def async_generator():
            async for page in self.pages:
                for response in page.intents:
                    yield response

        return async_generator()

    def __repr__(self) -> str:
        return "{0}<{1!r}>".format(self.__class__.__name__, self._response)


text:
class SystemMenuModelDelegate : public ui::SimpleMenuModel::Delegate {
 public:
  SystemMenuModelDelegate(ui::AcceleratorProvider* provider, Browser* browser);
  ~SystemMenuModelDelegate() override;

  Browser* browser() { return browser_; }

  // Overridden from ui::SimpleMenuModel::Delegate:
  bool IsCommandIdChecked(int command_id) const override;
  bool IsCommandIdEnabled(int command_id) const override;
  bool GetAcceleratorForCommandId(int command_id,
                                  ui::Accelerator* accelerator) override;
  bool IsItemForCommandIdDynamic(int command_id) const override;
  base::string16 GetLabelForCommandId(int command_id) const override;
  void ExecuteCommand(int command_id, int event_flags) override;

 private:
  ui::AcceleratorProvider* provider_;  // weak
  Browser* browser_;  // weak

  DISALLOW_COPY_AND_ASSIGN(SystemMenuModelDelegate);
};

#endif  // CHROME_BROWSER_UI_VIEWS_FRAME_SYSTEM_MENU_MODEL_DELEGATE_H_


text:
#ifndef FREERDP_LIB_PRIMTEST_H
#define FREERDP_LIB_PRIMTEST_H

#include <winpr/crt.h>
#include <winpr/spec.h>
#include <winpr/wtypes.h>
#include <winpr/platform.h>
#include <winpr/crypto.h>

#include <freerdp/primitives.h>

#include "measure.h"

#ifdef WITH_IPP
#include <ipps.h>
#include <ippi.h>
#endif

#ifdef _WIN32
#define ALIGN(x) x
#else
#define ALIGN(x) x DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT)
#endif

#define ABS(_x_) ((_x_) < 0 ? (-(_x_)) : (_x_))
#define MAX_TEST_SIZE 4096

extern int test_sizes[];
#define NUM_TEST_SIZES 10

extern BOOL g_TestPrimitivesPerformance;
extern UINT32 g_Iterations;

extern primitives_t* generic;
extern primitives_t* optimized;

void prim_test_setup(BOOL performance);

typedef pstatus_t (*speed_test_fkt)();

BOOL speed_test(const char* name, const char* dsc, UINT32 iterations,
		speed_test_fkt generic, speed_test_fkt optimized,
		...);

#endif /* FREERDP_LIB_PRIMTEST_H */


text:
/*
 * linux/fs/ext4/page-io.c
 *
 * This contains the new page_io functions for ext4
 *
 * Written by Theodore Ts'o, 2010.
 */

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/time.h>
#include <linux/jbd2.h>
#include <linux/highuid.h>
#include <linux/pagemap.h>
#include <linux/quotaops.h>
#include <linux/string.h>
#include <linux/buffer_head.h>
#include <linux/writeback.h>
#include <linux/pagevec.h>
#include <linux/mpage.h>
#include <linux/namei.h>
#include <linux/uio.h>
#include <linux/bio.h>
#include <linux/workqueue.h>
#include <linux/kernel.h>
#include <linux/slab.h>

#include "ext4_jbd2.h"
#include "xattr.h"
#include "acl.h"
#include "ext4_extents.h"

static struct kmem_cache *io_page_cachep, *io_end_cachep;

int __init ext4_init_pageio(void)
{
	io_page_cachep = KMEM_CACHE(ext4_io_page, SLAB_RECLAIM_ACCOUNT);
	if (io_page_cachep == NULL)
		return -ENOMEM;
	io_end_cachep = KMEM_CACHE(ext4_io_end, SLAB_RECLAIM_ACCOUNT);
	if (io_end_cachep == NULL) {
		kmem_cache_destroy(io_page_cachep);
		return -ENOMEM;
	}
	return 0;
}

void ext4_exit_pageio(void)
{
	kmem_cache_destroy(io_end_cachep);
	kmem_cache_destroy(io_page_cachep);
}

void ext4_ioend_wait(struct inode *inode)
{
	wait_queue_head_t *wq = ext4_ioend_wq(inode);

	wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_ioend_count) == 0));
}

static void put_io_page(struct ext4_io_page *io_page)
{
	if (atomic_dec_and_test(&io_page->p_count)) {
		end_page_writeback(io_page->p_page);
		put_page(io_page->p_page);
		kmem_cache_free(io_page_cachep, io_page);
	}
}

void ext4_free_io_end(ext4_io_end_t *io)
{
	int i;

	BUG_ON(!io);
	if (io->page)
		put_page(io->page);
	for (i = 0; i < io->num_io_pages; i++)
		put_io_page(io->pages[i]);
	io->num_io_pages = 0;
	if (atomic_dec_and_test(&EXT4_I(io->inode)->i_ioend_count))
		wake_up_all(ext4_ioend_wq(io->inode));
	kmem_cache_free(io_end_cachep, io);
}

/*
 * check a range of space and convert unwritten extents to written.
 *
 * Called with inode->i_mutex; we depend on this when we manipulate
 * io->flag, since we could otherwise race with ext4_flush_completed_IO()
 */
int ext4_end_io_nolock(ext4_io_end_t *io)
{
	struct inode *inode = io->inode;
	loff_t offset = io->offset;
	ssize_t size = io->size;
	int ret = 0;

	ext4_debug("ext4_end_io_nolock: io 0x%p from inode %lu,list->next 0x%p,"
		   "list->prev 0x%p\n",
		   io, inode->i_ino, io->list.next, io->list.prev);

	ret = ext4_convert_unwritten_extents(inode, offset, size);
	if (ret < 0) {
		ext4_msg(inode->i_sb, KERN_EMERG,
			 "failed to convert unwritten extents to written "
			 "extents -- potential data loss!  "
			 "(inode %lu, offset %llu, size %zd, error %d)",
			 inode->i_ino, offset, size, ret);
	}

	/* Wake up anyone waiting on unwritten extent conversion */
	if (atomic_dec_and_test(&EXT4_I(inode)->i_aiodio_unwritten))
		wake_up_all(ext4_ioend_wq(io->inode));
	if (io->flag & EXT4_IO_END_DIRECT)
		inode_dio_done(inode);
	if (io->iocb)
		aio_complete(io->iocb, io->result, 0);
	return ret;
}

/*
 * work on completed aio dio IO, to convert unwritten extents to extents
 */
static void ext4_end_io_work(struct work_struct *work)
{
	ext4_io_end_t		*io = container_of(work, ext4_io_end_t, work);
	struct inode		*inode = io->inode;
	struct ext4_inode_info	*ei = EXT4_I(inode);
	unsigned long		flags;

	spin_lock_irqsave(&ei->i_completed_io_lock, flags);
	if (io->flag & EXT4_IO_END_IN_FSYNC)
		goto requeue;
	if (list_empty(&io->list)) {
		spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
		goto free;
	}

	if (!mutex_trylock(&inode->i_mutex)) {
		bool was_queued;
requeue:
		was_queued = !!(io->flag & EXT4_IO_END_QUEUED);
		io->flag |= EXT4_IO_END_QUEUED;
		spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
		/*
		 * Requeue the work instead of waiting so that the work
		 * items queued after this can be processed.
		 */
		queue_work(EXT4_SB(inode->i_sb)->dio_unwritten_wq, &io->work);
		/*
		 * To prevent the ext4-dio-unwritten thread from keeping
		 * requeueing end_io requests and occupying cpu for too long,
		 * yield the cpu if it sees an end_io request that has already
		 * been requeued.
		 */
		if (was_queued)
			yield();
		return;
	}
	list_del_init(&io->list);
	spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
	(void) ext4_end_io_nolock(io);
	mutex_unlock(&inode->i_mutex);
free:
	ext4_free_io_end(io);
}

ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags)
{
	ext4_io_end_t *io = kmem_cache_zalloc(io_end_cachep, flags);
	if (io) {
		atomic_inc(&EXT4_I(inode)->i_ioend_count);
		io->inode = inode;
		INIT_WORK(&io->work, ext4_end_io_work);
		INIT_LIST_HEAD(&io->list);
	}
	return io;
}

/*
 * Print an buffer I/O error compatible with the fs/buffer.c.  This
 * provides compatibility with dmesg scrapers that look for a specific
 * buffer I/O error message.  We really need a unified error reporting
 * structure to userspace ala Digital Unix's uerf system, but it's
 * probably not going to happen in my lifetime, due to LKML politics...
 */
static void buffer_io_error(struct buffer_head *bh)
{
	char b[BDEVNAME_SIZE];
	printk(KERN_ERR "Buffer I/O error on device %s, logical block %llu\n",
			bdevname(bh->b_bdev, b),
			(unsigned long long)bh->b_blocknr);
}

static void ext4_end_bio(struct bio *bio, int error)
{
	ext4_io_end_t *io_end = bio->bi_private;
	struct workqueue_struct *wq;
	struct inode *inode;
	unsigned long flags;
	int i;
	sector_t bi_sector = bio->bi_sector;

	BUG_ON(!io_end);
	bio->bi_private = NULL;
	bio->bi_end_io = NULL;
	if (test_bit(BIO_UPTODATE, &bio->bi_flags))
		error = 0;
	bio_put(bio);

	for (i = 0; i < io_end->num_io_pages; i++) {
		struct page *page = io_end->pages[i]->p_page;
		struct buffer_head *bh, *head;
		loff_t offset;
		loff_t io_end_offset;

		if (error) {
			SetPageError(page);
			set_bit(AS_EIO, &page->mapping->flags);
			head = page_buffers(page);
			BUG_ON(!head);

			io_end_offset = io_end->offset + io_end->size;

			offset = (sector_t) page->index << PAGE_CACHE_SHIFT;
			bh = head;
			do {
				if ((offset >= io_end->offset) &&
				    (offset+bh->b_size <= io_end_offset))
					buffer_io_error(bh);

				offset += bh->b_size;
				bh = bh->b_this_page;
			} while (bh != head);
		}

		put_io_page(io_end->pages[i]);
	}
	io_end->num_io_pages = 0;
	inode = io_end->inode;

	if (error) {
		io_end->flag |= EXT4_IO_END_ERROR;
		ext4_warning(inode->i_sb, "I/O error writing to inode %lu "
			     "(offset %llu size %ld starting block %llu)",
			     inode->i_ino,
			     (unsigned long long) io_end->offset,
			     (long) io_end->size,
			     (unsigned long long)
			     bi_sector >> (inode->i_blkbits - 9));
	}

	if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) {
		ext4_free_io_end(io_end);
		return;
	}

	/* Add the io_end to per-inode completed io list*/
	spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags);
	list_add_tail(&io_end->list, &EXT4_I(inode)->i_completed_io_list);
	spin_unlock_irqrestore(&EXT4_I(inode)->i_completed_io_lock, flags);

	wq = EXT4_SB(inode->i_sb)->dio_unwritten_wq;
	/* queue the work to convert unwritten extents to written */
	queue_work(wq, &io_end->work);
}

void ext4_io_submit(struct ext4_io_submit *io)
{
	struct bio *bio = io->io_bio;

	if (bio) {
		bio_get(io->io_bio);
		submit_bio(io->io_op, io->io_bio);
		BUG_ON(bio_flagged(io->io_bio, BIO_EOPNOTSUPP));
		bio_put(io->io_bio);
	}
	io->io_bio = NULL;
	io->io_op = 0;
	io->io_end = NULL;
}

static int io_submit_init(struct ext4_io_submit *io,
			  struct inode *inode,
			  struct writeback_control *wbc,
			  struct buffer_head *bh)
{
	ext4_io_end_t *io_end;
	struct page *page = bh->b_page;
	int nvecs = bio_get_nr_vecs(bh->b_bdev);
	struct bio *bio;

	io_end = ext4_init_io_end(inode, GFP_NOFS);
	if (!io_end)
		return -ENOMEM;
	bio = bio_alloc(GFP_NOIO, min(nvecs, BIO_MAX_PAGES));
	bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9);
	bio->bi_bdev = bh->b_bdev;
	bio->bi_private = io->io_end = io_end;
	bio->bi_end_io = ext4_end_bio;

	io_end->offset = (page->index << PAGE_CACHE_SHIFT) + bh_offset(bh);

	io->io_bio = bio;
	io->io_op = (wbc->sync_mode == WB_SYNC_ALL ?  WRITE_SYNC : WRITE);
	io->io_next_block = bh->b_blocknr;
	return 0;
}

static int io_submit_add_bh(struct ext4_io_submit *io,
			    struct ext4_io_page *io_page,
			    struct inode *inode,
			    struct writeback_control *wbc,
			    struct buffer_head *bh)
{
	ext4_io_end_t *io_end;
	int ret;

	if (buffer_new(bh)) {
		clear_buffer_new(bh);
		unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr);
	}

	if (!buffer_mapped(bh) || buffer_delay(bh)) {
		if (!buffer_mapped(bh))
			clear_buffer_dirty(bh);
		if (io->io_bio)
			ext4_io_submit(io);
		return 0;
	}

	if (io->io_bio && bh->b_blocknr != io->io_next_block) {
submit_and_retry:
		ext4_io_submit(io);
	}
	if (io->io_bio == NULL) {
		ret = io_submit_init(io, inode, wbc, bh);
		if (ret)
			return ret;
	}
	io_end = io->io_end;
	if ((io_end->num_io_pages >= MAX_IO_PAGES) &&
	    (io_end->pages[io_end->num_io_pages-1] != io_page))
		goto submit_and_retry;
	if (buffer_uninit(bh))
		ext4_set_io_unwritten_flag(inode, io_end);
	io->io_end->size += bh->b_size;
	io->io_next_block++;
	ret = bio_add_page(io->io_bio, bh->b_page, bh->b_size, bh_offset(bh));
	if (ret != bh->b_size)
		goto submit_and_retry;
	if ((io_end->num_io_pages == 0) ||
	    (io_end->pages[io_end->num_io_pages-1] != io_page)) {
		io_end->pages[io_end->num_io_pages++] = io_page;
		atomic_inc(&io_page->p_count);
	}
	return 0;
}

int ext4_bio_write_page(struct ext4_io_submit *io,
			struct page *page,
			int len,
			struct writeback_control *wbc)
{
	struct inode *inode = page->mapping->host;
	unsigned block_start, block_end, blocksize;
	struct ext4_io_page *io_page;
	struct buffer_head *bh, *head;
	int ret = 0;

	blocksize = 1 << inode->i_blkbits;

	BUG_ON(!PageLocked(page));
	BUG_ON(PageWriteback(page));

	io_page = kmem_cache_alloc(io_page_cachep, GFP_NOFS);
	if (!io_page) {
		set_page_dirty(page);
		unlock_page(page);
		return -ENOMEM;
	}
	io_page->p_page = page;
	atomic_set(&io_page->p_count, 1);
	get_page(page);
	set_page_writeback(page);
	ClearPageError(page);

	for (bh = head = page_buffers(page), block_start = 0;
	     bh != head || !block_start;
	     block_start = block_end, bh = bh->b_this_page) {

		block_end = block_start + blocksize;
		if (block_start >= len) {
			/*
			 * Comments copied from block_write_full_page_endio:
			 *
			 * The page straddles i_size.  It must be zeroed out on
			 * each and every writepage invocation because it may
			 * be mmapped.  "A file is mapped in multiples of the
			 * page size.  For a file that is not a multiple of
			 * the  page size, the remaining memory is zeroed when
			 * mapped, and writes to that region are not written
			 * out to the file."
			 */
			zero_user_segment(page, block_start, block_end);
			clear_buffer_dirty(bh);
			set_buffer_uptodate(bh);
			continue;
		}
		clear_buffer_dirty(bh);
		ret = io_submit_add_bh(io, io_page, inode, wbc, bh);
		if (ret) {
			/*
			 * We only get here on ENOMEM.  Not much else
			 * we can do but mark the page as dirty, and
			 * better luck next time.
			 */
			set_page_dirty(page);
			break;
		}
	}
	unlock_page(page);
	/*
	 * If the page was truncated before we could do the writeback,
	 * or we had a memory allocation error while trying to write
	 * the first buffer head, we won't have submitted any pages for
	 * I/O.  In that case we need to make sure we've cleared the
	 * PageWriteback bit from the page to prevent the system from
	 * wedging later on.
	 */
	put_io_page(io_page);
	return ret;
}


text:
class CreateCategories < ActiveRecord::Migration[5.1]
  def change
    create_table :categories do |t|
      t.string :name

      t.timestamps
    end
  end

  def down
    remove_columns :name
  end
end


text:
/*
	Mostly discarded code, kept for reference and more readily
	available documentation of my thought process than git logs .
*/
#include "snippets.h"
#include "lib_window.h"

#include <stdio.h>
#include <math.h>

void snippets::calc_text_rect_2(RECT & rc, HDC dc,
		LPCTSTR text, size_t text_len)
{
	SIZE text_size;
	GetTextExtentPoint32(dc, text, text_len, &text_size);
	rc.right = rc.left + text_size.cx;
	rc.bottom = rc.top + text_size.cy;
}

void snippets::calc_text_rect_1(RECT & rc, HDC dc,
		lib::font::EnumFontInfo & fi,
		LPCTSTR text, size_t text_len)
{
	lib::font::EnumFontInfoLoader efil(dc, fi);

	SIZE text_size;
	GetTextExtentPoint32(dc, text, text_len, &text_size);
	rc.right = rc.left + text_size.cx;
	rc.bottom = rc.top + text_size.cy;
}

snippets::ScrollBar::ScrollBar(int nBar)
		: parent(nullptr), bar_id(nBar)
{
}

void snippets::ScrollBar::show(bool on)
{
	ShowScrollBar(parent, bar_id, on ? TRUE : FALSE);
}

void snippets::ScrollBar::set_count(size_t _count)
{
	count = _count ? _count - 1 : 0;
	SetScrollRange(parent, bar_id, 0, count, FALSE);
	show(count > 0);
}

bool snippets::ScrollBar::scroll(int steps, bool update)
{
	if (count == 0) return false;

	size_t temp = index;

	if (steps > 0)
	{
		if (count - index <= (size_t) steps)
		{
			temp = count;
		}
		else if (index + steps <= count)
		{
			temp += steps;
		}
	}
	else if (steps < 0)
	{
		if (index <= (size_t) -steps)
		{
			temp = 0;
		}
		else if (index > (size_t) -steps)
		{
			temp += steps;
		}
	}

	if (temp == index) return false;
	index = temp;

	if (update) this->update();

	return true;
}

void snippets::ScrollBar::update()
{
	SetScrollPos(parent, bar_id, index, TRUE);
}

snippets::RowIndexDrawer::RowIndexDrawer()
		: format{_T("%3d")}, buffer{0}
{
	HDC dc = GetDC(nullptr);
	SelectObject(dc, GetStockObject(ANSI_FIXED_FONT));
	GetTextMetrics(dc, &tm);
	ReleaseDC(nullptr, dc);
}

int snippets::RowIndexDrawer::get_height(float scale) const
{
	return int(tm.tmHeight * scale);
}

void snippets::RowIndexDrawer::set_digits(unsigned count)
{
	_sntprintf(format, sizeof(format),
		count >= 2 ? _T("%%%dd") : _T("%%d"), count);
}

void snippets::RowIndexDrawer::set_digits_from_max_index(size_t index)
{
	if (last_max_index == index) return;
	set_digits(floor(log10(index ? index : 1) + 1));
	last_max_index = index;
}

void snippets::RowIndexDrawer::draw(HDC dc, RECT & rc,
		int index, LPCTSTR format)
{
	if (!format || !*format) format = this->format;
	_sntprintf(buffer, sizeof(buffer), format, index);

	SetBkMode(dc, TRANSPARENT);
	HGDIOBJ old_font = SelectObject(dc, GetStockObject(ANSI_FIXED_FONT));
	text_draw_2(dc, rc, buffer, _tcslen(buffer));
	SelectObject(dc, old_font);
	SetBkMode(dc, OPAQUE);
}

void snippets::text_draw_1(HDC dc, RECT & rc,
		LPCTSTR text, size_t text_len)
{
	RECT tr = {rc.left, rc.top, 0, 0};
	calc_text_rect_2(tr, dc, text, text_len);

	UINT const ta_old = SetTextAlign(dc, TA_UPDATECP);

	MoveToEx(dc, rc.left, rc.top, nullptr);
	ExtTextOut(dc, rc.left, rc.top,
		0, nullptr, text, text_len, nullptr);

	MoveToEx(dc, rc.left, rc.top, (LPPOINT) &rc.right);
	rc.bottom = tr.bottom;

	if (GDI_ERROR != ta_old)
		SetTextAlign(dc, ta_old);
}

void snippets::text_draw_2(HDC dc, RECT & rc,
		LPCTSTR text, size_t text_len)
{
	calc_text_rect_2(rc, dc, text, text_len);
	TextOut(dc, rc.left, rc.top, text, text_len);
}


text:
'''
Created on Jun 1, 2015

@author: Alex
'''
from ScanModules import BaseModule

class HTTPSModule(BaseModule):
    '''
    classdocs
    '''

    def __init__(self, params):
        '''
        Constructor
        '''
        super(HTTPSModule,self).__init__()


text:
package com.idiazt.springaopaspectjannotationsfullexample.aspects;

import java.lang.annotation.Annotation;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.idiazt.springaopaspectjannotationsfullexample.aspects.annotations.LogObject;
import com.idiazt.springaopaspectjannotationsfullexample.aspects.annotations.LogObject.LogObjectLevel;
import com.idiazt.springaopaspectjannotationsfullexample.util.ReflectionUtil;

@Aspect
public class RetrieveObjectsAspect {

	private static Logger logger = LoggerFactory
			.getLogger(RetrieveObjectsAspect.class);

	@Pointcut("execution(@com.idiazt.springaopaspectjannotationsfullexample.aspects.annotations.LogObject * *.*(..))")
	public void logAnnotatedMethods() {
		// Extract from
		// https://eclipse.org/aspectj/doc/next/adk15notebook/ataspectj-pcadvice.html
		// As a general rule, the @Pointcut annotated method must have an empty
		// method body and must not have any throws clause. If formal are bound
		// (using args(), target(), this(), @args(), @target(), @this(),
		// @annotation()) in the pointcut, then they must appear in the method
		// signature.
	}

	@Before("logAnnotatedMethods()")
	public void executeBefore() {
		logger.info("Entering the aspect...");
	}

	@After("logAnnotatedMethods()")
	public void executeAfter() {
		logger.info("Leaving the aspect...");
	}

	@Around("logAnnotatedMethods()")
	public Object executeAround(ProceedingJoinPoint joinpoint) {
		try {
			Object result = joinpoint.proceed();
			Annotation annotation = ReflectionUtil
					.getAnnotationFromJoinpointMethod(joinpoint,
							LogObject.class);
			if (((LogObject) annotation).nivel().equals(LogObjectLevel.DEBUG))
				logger.info(result.toString());
			return result;
		} catch (Throwable e) {
			throw new RuntimeException(e);
		}
	}
}


text:
<types>
    <type>
        <struct name="InnerStruct">
            <member name="inner_count" type="byte"/>
        </struct>
    </type>
    <type>
        <struct name="TypeLookup">
            <member name="message" type="string"/>
            <member name="index" type="uint32"/>
            <member name="count" type="nonBasic" nonBasicTypeName="InnerStruct"/>
        </struct>
    </type>
</types>


text:
testrepos2
==========

viel  mehr Text **das ist fett**


text:
<Alloy>
    <ItemTemplate name="spacerTemplate" backgroundColor="black" selectedBackgroundColor="transparent" height="Ti.UI.SIZE">
        <View class="box" height="15" />
    </ItemTemplate>
</Alloy>


text:
SELECT CONVERT(VARCHAR(11), m.DatePlayed, 106) AS [Match Date],
	p.FirstName + ' ' + p.LastName AS [Winner],
	pp.FirstName + ' ' + pp.LastName AS [Loser],
	m.Result,
	po.Points AS [Points Won],
	t.Name AS [Tournament],
    c.Name AS [City],
	co.Name AS [Country]
FROM Matches m
JOIN Tournaments t ON t.Id = m.TournamentId
JOIN PointDistributionKeys po ON po.CategoryId = t.CategoryId AND po.RoundId = (m.RoundId + 1)
JOIN Cities c ON c.Id = t.CityId
JOIN Players p ON m.WinnerId = p.Id
JOIN Players pp ON m.LoserId = pp.Id
JOIN Countries co ON c.CountryId = co.Id


text:
<?php
$dom = new DOMDocument();
$dom->loadXML("<root><foo>foobar</foo><foo>foobar#2</foo></root>");

$nodelist = $dom->getElementsByTagName("foo");

var_dump($nodelist->length, isset($nodelist->length), isset($nodelist->foo));
var_dump(empty($nodelist->length), empty($nodelist->foo));
?>


text:
package drivers

// Info represents information about a storage driver.
type Info struct {
	Name                  string
	Version               string
	VolumeTypes           []VolumeType // Supported volume types.
	Remote                bool         // Whether the driver uses a remote backing store.
	VolumeMultiNode       bool         // Whether volumes can be used on multiple nodes concurrently.
	OptimizedImages       bool         // Whether driver stores images as separate volume.
	OptimizedBackups      bool         // Whether driver supports optimized volume backups.
	OptimizedBackupHeader bool         // Whether driver generates an optimised backup header file in backup.
	PreservesInodes       bool         // Whether driver preserves inodes when volumes are moved hosts.
	BlockBacking          bool         // Whether driver uses block devices as backing store.
	RunningCopyFreeze     bool         // Whether instance should be frozen during snapshot if running.
	DirectIO              bool         // Whether the driver supports direct I/O.
	MountedRoot           bool         // Whether the pool directory itself is a mount.
}

// VolumeFiller provides a struct for filling a volume.
type VolumeFiller struct {
	Fill func(vol Volume, rootBlockPath string, allowUnsafeResize bool) (int64, error) // Function to fill the volume.
	Size int64                                                                         // Size of the unpacked volume in bytes.

	Fingerprint string // If the Filler will unpack an image, it should be this fingerprint.
}


text:
using System.Threading.Tasks;
using UsersDomain.Entities.Registration;
using UsersDomain.Repositories.Registration;
using UsersDomain.Services.Registration;
using UsersDomain.ValueTypes;
using UsersDomain.ValueTypes.Confirmation;
using UsersDomain.ValueTypes.Registration;
using UsersService.Controllers.Data;
using UsersService.Logs;

namespace UsersService.Commands.CreateRegistrationRequest
{
    public class Command : ICommand
    {
        private readonly IGetConfirmationLinkStrategy confirmationLink;
        private readonly IRequests requestsRepository;
        private readonly IEmail emailService;
        private readonly ILog log;

        private RegistrationData registrationData;
        private Request registrationRequest;
        private Email registrationEmail;

        public Command(IGetConfirmationLinkStrategy confirmationLink,
                       IRequests requestsRepository,
                       IEmail emailService,
                       ILog log,
                       RegistrationData registrationData)
        {
            this.confirmationLink = confirmationLink;
            this.requestsRepository = requestsRepository;
            this.emailService = emailService;
            this.log = log;
            this.registrationData = registrationData;
        }

        public async Task ExecuteAsync()
        {
            CreateRegistrationRequest();
            await SaveRegistrationRequestAsync();
            LogThatRequestIsSaved();
            CreateRegistrationEmail();
            await SendRegistrationEmailAsync();
            LogThatEmailIsSent();
        }

        private void CreateRegistrationRequest()
        {
            var login = new Login(registrationData.Login);
            var password = new Password(registrationData.Password);
            registrationRequest = Request.Create(login, password);
        }

        private async Task SaveRegistrationRequestAsync()
        {
            await registrationRequest.SaveAsync(requestsRepository);
        }

        private void LogThatRequestIsSaved()
        {
            log.Information($"Registration request with id {registrationRequest.Id} has saved for login {registrationData.Login}");
        }

        private void CreateRegistrationEmail()
        {
            var url = confirmationLink.GetForRequestId(registrationRequest.Id);
            var link = new Link(url);
            registrationEmail = registrationRequest.CreateEmailWithConfirmationLink(link);
        }

        private async Task SendRegistrationEmailAsync()
        {
            await registrationEmail.SendAsync(emailService);
        }

        private void LogThatEmailIsSent()
        {
            log.Information($"Email for login {registrationData.Login} has sent");
        }
    }
}


text:
<!doctype html>

    <meta charset="utf-8">
    <title>Sample Localization Page</title>

Sample Page Document

Sample Page Subtitle

Sample paragraph. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam vestibulum mollis metus non porttitor. Etiam molestie tincidunt ipsum, vitae pulvinar urna malesuada non.

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Nam vestibulum mollis metus non porttitor.

Etiam molestie tincidunt ipsum, vitae pulvinar urna malesuada non.


text:
class TTree;
class TH2F;
class TH2D;
class TH2;
class TF1;
class RooBinning;
class RooArgList;
class RooDataHist;
class RooCurve;
class RooAbsPdf;
class RooArgSet;

#include "RooDataHist.h"
#include "RooRealVar.h"
#include "RooAbsPdf.h"
#include "RooBinning.h"
#include "RooFitResult.h"
#include <vector>

namespace BinningUtil
{
  void getBinning( RooBinning& binning, RooRealVar& x, RooAbsReal& func );
  double nextstep(TF1* wf, double x0, double x1);

  void randomizeBinned( RooDataHist& myCopy );

  std::vector<RooDataHist> dataVariations(RooArgList& parList, const RooDataHist& input, const double& scale=1.0, const double& cutoff=-1.0 );
  std::vector<RooDataHist> histVariations(RooRealVar& x, const std::vector<RooDataHist>& inputVec, const double& rho=1.0,
                                          const TString& options="am", const Int_t& nSigma=3,
                                          const Bool_t& rotation=kTRUE, const Bool_t& sortInput=kTRUE);

  void pdfVariations(RooArgList&, RooRealVar& x, const std::vector<RooDataHist>& inputVec);

  void createPdf( RooArgList& parList, RooArgList& pdfList, RooRealVar& x, const RooDataHist& input,
		  const TString& options, const double& rho, const Int_t& nSigma, const Bool_t& rotation, const Bool_t& sortInput,
		  const double& scale, const double& cutoff );

  RooCurve* plotOnWithErrorBand( RooPlot* frame, Double_t Z, RooAbsPdf& pdf, RooArgSet& obs, const int& nCurves=-1, const int& nEvents=-1,
				 const char* binning=0, RooDataHist* dataHist=0 );

  RooDataHist* makeAsimov1D( const RooAbsPdf& pdf, RooRealVar& obs, const RooBinning& binning, const char* binningName, TH1* ehist=0 );

  RooDataHist* makeAsimov1DScale( const RooAbsPdf& pdf, RooRealVar& obs, const RooBinning& binning, const char* binningName, const double& scale,
				  const Bool_t& overwrite, RooRealVar& overwriteObs );

  void setAverageErrors( RooDataHist& data, const RooDataHist& input1, const RooDataHist& input2);

  RooDataHist* makeAsimov1DError( const RooAbsPdf& pdf, RooRealVar& obs, const RooBinning& binning, const char* binningName, const RooFitResult& result );

  void copyScaleAndErrors( RooDataHist& data, const RooDataHist& input) ;

}
#endif


text:
<?php declare(strict_types = 1);
namespace com\qetrix\libs;

final class QElem
{
	// Type properties
	protected $_id = ""; /// Primary Key, null = new (not in DS yet) => dsname (t_pk)
	protected $_ds; /// DataStore: engine.table (tds)
	protected $_name; /// Lang key for name (tn)
	protected $_desc = ""; /// Description / detail
	protected $_parent = ""; /// Parent type => parent dsname
	protected $tmo = 1; /// Max occurences in class. -1 = is ent, 0 = disabled, 1 = single, 2 = multiple (complex)
	protected $_order = 0; /// Order in class (toc)
	protected $_valueType = ElemType::text; // Value type (tvt)
	protected $_valueUnit = ""; /// Value unit (SI, if possible) (tvu)
	/** @var ElemMode */
	protected $_valueMode = ElemMode::normal; // Value mode (R/O, req, unique...) (tvm)
	protected $_valueMin = null; /// Float, Min value (num) / min length (str) (tvn)
	protected $_valueMax = null; /// Float, Max value (num) / max length (str) (tvx)
	protected $_valuePrecision = null; /// Float, Value precision (tvp)
	protected $_valueValidation = ""; /// Value validation (tvv)
	protected $_valueDefault = ""; /// Default value (tvd)
	//protected $trt = RelationType::none; // Relation type
	//protected $trm = RelationMode::hidden; // Relation mode
	protected $_relationList = 0; // Relation list (domain - Particle ID or Class ID) (trl)
	//protected $tot = OrderType::none; // Order type
	protected $_tag = ""; // QetriX Tag for specific purposes (marked as parent, coords, user...) (tg)

	// Value properties
	protected $_action = "";
	protected $_compname = ""; // Parent component name
	protected $_items = []; // List<QItem>
	protected $_label = ""; // Control label or column heading
	protected $_style = "";
	protected $_text = "";
	protected $_values = []; // Current value

	/** Delm - Control in QForm or column in QList
	 *
	 * @param mixed $data Array of Delm data OR numeric ValueType/RelationType/OrderType OR string name of Det
	 * @param string $name Name
	 * @param string $label Label
	 * @param string $value Value
	 * @param int $order Order - higher number = lower in QForm or further right in QList
	 * @param array $items Array of QItems
	 *
	 * @internal param $mix
	 */
	function __construct($data = null, $name = "", $label = "", $value = "", $order = null, array $items = [])
	{
		return $this->QElem($data, $name, $label, $value, $order, $items);
	}

	/**
	 * @param null $data
	 * @param string $name
	 * @param string $label
	 * @param string $value Default value; might be replaced by QForm->data([...]), if present
	 * @param int $order
	 * @param array $items
	 *
	 * @throws \Exception
	 * @return $this
	 */
	public function QElem($data = null, $name = "", $label = "", $value = "", $order = null, array $items = [])
	{
		if ($data === null) return $this;
		if (is_array($data)) foreach ($data as $k => $v) {
			$prop = (property_exists($this, $k) ? "" : "_").$k;
			if ($prop == $k || property_exists($this, $prop)) $this->$prop = $v;
			if (isset($data["value"])) $this->_values = [$data["value"]];
		} elseif (is_numeric($data)) {
			if ($name != "" && strpos($name."", "-") !== false) throw new \Exception("Invalid QElem name: ".$name." (should be: ".str_replace("-", "", $name).")");
			$this->_name = $name.""; // "" = autonaming
			$this->_id = $name.""; // dsname
			$this->_valueType = $data;
			if (($data > 99 && $data < 200) || substr($name."", -2) == "_r") {
				$this->_ds = substr($name, 0, -2);
				$this->value($value);
				$this->text($value);
			} elseif ($data > 199 || substr($name."", -2) == "_o") {
				$this->_ds = substr($name, 0, -2);
				$this->value($value);
			} else {
				$this->_ds = $name."";
				$this->value($value);
			}
			$this->_label = $label == "" && $this->_valueType != ElemType::result ? $name."" : $label; // label = "" => name + lang
			$this->_valueDefault = $value; // Set default value
			$this->_order = $order == "" ? null : $order;
			if (count($items) > 0) $this->items($items); // Create list of items
		} elseif (is_string($data)) {
			$this->_name = $data;
		}
		return $this;
	}

	/** Element name in DataStore (database table column, JSON object key). Used in backend.
	 *
	 * @param bool $value
	 *
	 * @return string|QElem
	 */
	public function dsname($value = false)
	{
		if ($value === false) return $this->_id;
		$this->_id = $value;
		return $this;
	}

	public function ds($value = false)
	{
		if ($value === false) return $this->_ds;
		$this->_ds = $value;
		return $this;
	}

	/** Element name in HTML. Used in frontend.
	 *
	 * @param null $value
	 *
	 * @return string|QElem
	 */
	public function name($value = null)
	{
		if ($value === null) return $this->_name;
		$this->_name = $value."";
		return $this;
	}

	/** Name of the component, to which the QElem belongs
	 *
	 * @param bool|string $value
	 *
	 * @return QElem|string
	 */
	public function compName($value = false)
	{
		if ($value === false) return $this->_compname;
		$this->_compname = $value;
		return $this;
	}

	/** Parent control (defining lowest value or filter for multi-level enums or ID of enum - dual Maximo style)
	 *
	 * @param bool $value
	 *
	 * @return string|QElem
	 */
	public function parent($value = false)
	{
		if ($value === null) return $this->_parent;
		$this->_parent = $value;
		return $this;
	}

	/** Set a value; won't be replaced by QForm->data([...])
	 *
	 * @param string|bool $value
	 * @param int $index
	 *
	 * @return QElem|string
	 * @throws \Exception
	 */
	public function value($value = null, $index = 0)
	{
		if ($value === null) return isset($this->_values[$index]) ? $this->_values[$index] : "";

		if (is_array($value)) $value = json_encode($value);
		elseif (is_string($value)) $value = trim($value);

		if (strlen($value."") > 0) {
			if ($this->_valueMin !== null) {
				if ($this->type() == ElemType::text && mb_strLen($value) < $this->_valueMin) throw new \Exception("Value (".$value.") must be at lest ".$this->_valueMin." chars long");
				if ($this->type() == ElemType::number && $value < $this->_valueMin) throw new \Exception("Value (".$value.") can't be smaller, than ".$this->_valueMin."");
				// TODO: DATE, TIME...
			}

			if ($this->_valueMax !== null) {
				if ($this->type() == ElemType::text && mb_strLen($value) > $this->_valueMax) throw new \Exception("Value (".$value.") can't be longer, than ".$this->_valueMax." chars");
				if ($this->type() == ElemType::number && $value > $this->_valueMax) throw new \Exception("Value (".$value.") can't be greater, than ".$this->_valueMax."");
				// TODO: DATE, TIME...
			}
			if ($this->_valuePrecision !== null) {
				// TODO: Number
				// TODO: Date (weeks, months, years)
			}

			// TODO: Check parent's value?
		}
		$this->_values[$index] = $value;
		return $this;
	}

	/** Set or get array of values
	 *
	 * @param null $values
	 *
	 * @return QElem|array
	 */
	public function values($values = null)
	{
		if ($values === null) return $this->_values;
		for ($i = 0; $i < count($values); $i++) $this->value($values[$i], $i);
		return $this;
	}

	public function defaultValue()
	{
		return $this->_valueDefault;
	}

	/**
	 * @param null $value
	 *
	 * @return QElem|string
	 */
	public function type($value = null)
	{
		if ($value === null) return $this->_valueType;
		$this->_valueType = $value;
		return $this;
	}

	/**
	 * @param null $value
	 *
	 * @return QElem|ElemMode
	 */
	public function mode($value = null)
	{
		if ($value === null) return $this->_valueMode;
		$this->_valueMode = $value;
		return $this;
	}

	/// For string value: min length
	/// For numeric value: min value
	/// For date and datetime: earliest date yyyymmdd (incl. entered date)
	/// For time: min seconds
	public function min($value = null)
	{
		if ($value === null) return $this->_valueMin;
		$this->_valueMin = $value;
		return $this;
	}

	/// For string value: max length
	/// For numeric value: max value
	/// For date and datetime: furthest date yyyymmdd (incl. entered date)
	/// For time: max seconds
	public function max($value = null)
	{
		if ($value === null) return $this->_valueMax;
		$this->_valueMax = $value;
		return $this;
	}

	/** Value precision
	 * Number: 100=hundreads, 10=tens, 0.1=1/10, 0.01=1/100
	 * DateTime: 1=Century, 2=Decade, 3=Year, 4=Quarter, 5=Month, 6=Week, 7=Day, 8=Hour, 9=Minute, 10=Second
	 * Time (duration): In seconds; 86400 = day, 3600 = hour, 300 = 5 mins, 60 = min, 0.01 = 1/100 sec
	 */
	public function precision($value = null)
	{
		if ($value === null) return $this->_valuePrecision;
		if ($value == 0) $value = null;
		$this->_valuePrecision = $value;
		return $this;
	}

	/** Value validation, list or regexp */
	public function validation($value = null)
	{
		if ($value === null) return $this->_valueValidation;
		$this->_valueValidation = $value;
		return $this;
	}

	public function validate()
	{
		throw new \Exception("Validation not yet implemented");
	}

	/** For textbox it's a placeholder
	 *
	 * @param null $value
	 *
	 * @return string|QElem
	 */
	public function text($value = null)
	{
		//if ($value === null) return $this->value() == "" ? "" : $this->_text; // No value = no text
		if ($value === null) return $this->_text; // Because $tableColDet->text() should return text
		$this->_text = $value;
		return $this;
	}

	/** xxx
	 *
	 * @param null $value
	 *
	 * @return QElem|string
	 */
	public function unit($value = null)
	{
		if ($value === null) return $this->_valueUnit;
		$this->_valueUnit = $value;
		return $this;
	}

	/** For textbox it's help or value descriptoin
	 *
	 * @param string $value
	 *
	 * @return QElem|string
	 */
	public function detail($value = null)
	{
		if ($value === null) return $this->_desc;
		$this->_desc = $value;
		return $this;
	}

	/** UI interpretation or CSS class(es) in HTML
	 *
	 * @param string $value
	 *
	 * @return string|QElem
	 */
	public function style($value = null)
	{
		if ($value === null) return $this->_style;
		$this->_style = $value;
		return $this;
	}

	/**
	 * @param null $value
	 *
	 * @return int|QElem
	 */
	public function order($value = null)
	{
		if ($value === null) return $this->_order;
		$this->_order = $value;
		return $this;
	}

	/** Gets or sets items for the type
	 *
	 * @param array|bool $value Values
	 *
	 * @return array|QElem
	 */
	public function items($value = false)
	{
		if ($value === false) return $this->_items;
		if (is_array($value)) {
			$arrType = Util::getArrayType($value);
			if ($arrType == 1) foreach ($value as $val) $this->_items[] = new QItem(["value" => $val, "text" => $val]);
			elseif ($arrType == 4) foreach ($value as $val) $this->_items[] = new QItem($val);
			else foreach ($value as $key => $val) $this->_items[] = new QItem(["value" => $key, "text" => $val]);
			return $this;
		} elseif (func_num_args() > 1) {
			$value = func_get_args();
			foreach ($value as $val) $this->_items[] = new QItem(["value" => $val, "text" => $val]);
			return $this;
		}
		foreach ($this->_items as $item) if ($item->value() == $value) return $item;
		return $this;
	}

	public function hasItems()
	{
		return !empty($this->_items);
	}

	public function hasValue()
	{
		return !empty($this->_values);
	}

	/** Set label
	 *
	 * @param string $value
	 *
	 * @return string|QElem
	 */
	public function label($value = null)
	{
		if ($value === null) return $this->_label;
		$this->_label = $value;
		return $this;
	}

	/** Set action
	 *
	 * @param string $value
	 *
	 * @return string|QElem
	 */
	public function action($value = null)
	{
		if ($value === null) return $this->_action;
		$this->_action = $value;
		return $this;
	}

	/** Set visibility (idea: just bool to hide the control/column)
	 *
	 * @param bool $value
	 *
	 * @return bool|QElem
	 */
	public function visible($value = null)
	{
		if ($value === null) return $this->mode() != ElemMode::hidden && $this->type() != ElemMode::hidden;
		$this->mode($value ? ElemMode::hidden : ElemMode::normal); // TODO: normal might replace previous mode setting!!
		return $this;
	}
}

abstract class ElemType extends QEnum
{
	const class_ = 1;
	const result = 3; /// Computed
	const const_ = 4; /// Value is not copied into object
	const enum = 6; /// Enum with elems or items

	const button = -1;

	const boolean = 10; /// 1/0 (as Yes/No) - checkbox
	const number = 12; /// Integer or Decimal number (MAIN)

	const longtext = 20;
	const text = 24; /// Any value (MAIN)

	const datetime = 30; /// YYYYMMDDhhmmss (MAIN)
	const time = 36; /// duration in decimal seconds (s.sss; output: 1d 16h 31m)

	const file = 50;

	const relation = 110;
}

abstract class ElemMode extends QEnum
{
	const hidden = 0; // Input type = hidden
	const disabled = 2; // Not editable
	const plain = 3; // Plain text, no control, not editable
	const normal = 4;
	const expected = 5; // Marked "+", must be filled to progress into next stage (like "validated")
	const required = 6; // Marked "*", must be filled to process (typically save) the form
	const unique = 8; // Unique value in the class it belongs to, it also is required (empty = not unique)
}

abstract class DateTimePrecision extends QEnum
{
	const century = 1;
	const decade = 2;
	const year = 3;
	const quarterYear = 4;
	const month = 5;
	const week = 6;
	const day = 7;
	const hour = 8;
	const minute = 9;
	const second = 10;
}