text:
package routers

import (
	"fmt"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"

	"code.gitea.io/gitea/models"
	"code.gitea.io/gitea/modules/base"
	"code.gitea.io/gitea/modules/context"
	"code.gitea.io/gitea/modules/generate"
	"code.gitea.io/gitea/modules/graceful"
	"code.gitea.io/gitea/modules/log"
	"code.gitea.io/gitea/modules/setting"
	"code.gitea.io/gitea/modules/templates"
	"code.gitea.io/gitea/modules/translation"
	"code.gitea.io/gitea/modules/user"
	"code.gitea.io/gitea/modules/util"
	"code.gitea.io/gitea/modules/web"
	"code.gitea.io/gitea/modules/web/middleware"
	"code.gitea.io/gitea/services/forms"

	"gitea.com/go-chi/session"
	"gopkg.in/ini.v1"
)

const (
	// tplInstall template for installation page
	tplInstall     base.TplName = "install"
	tplPostInstall base.TplName = "post-install"
)

// InstallInit prepare for rendering installation page
func InstallInit(next http.Handler) http.Handler {
	var rnd = templates.HTMLRenderer()

	return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
		if setting.InstallLock {
			resp.Header().Add("Refresh", "1; url="+setting.AppURL+"user/login")
			_ = rnd.HTML(resp, 200, string(tplPostInstall), nil)
			return
		}
		var locale = middleware.Locale(resp, req)
		var startTime = time.Now()
		var ctx = context.Context{
			Resp:    context.NewResponse(resp),
			Flash:   &middleware.Flash{},
			Locale:  locale,
			Render:  rnd,
			Session: session.GetSession(req),
			Data: map[string]interface{}{
				"Title":         locale.Tr("install.install"),
				"PageIsInstall": true,
				"DbOptions":     setting.SupportedDatabases,
				"i18n":          locale,
				"Language":      locale.Language(),
				"Lang":          locale.Language(),
				"AllLangs":      translation.AllLangs(),
				"CurrentURL":    setting.AppSubURL + req.URL.RequestURI(),
				"PageStartTime": startTime,
				"TmplLoadTimes": func() string {
					return time.Since(startTime).String()
				},
				"PasswordHashAlgorithms": models.AvailableHashAlgorithms,
			},
		}
		for _, lang := range translation.AllLangs() {
			if lang.Lang == locale.Language() {
				ctx.Data["LangName"] = lang.Name
				break
			}
		}
		ctx.Req = context.WithContext(req, &ctx)
		next.ServeHTTP(resp, ctx.Req)
	})
}

// Install render installation page
func Install(ctx *context.Context) {
	form := forms.InstallForm{}

	// Database settings
	form.DbHost = setting.Database.Host
	form.DbUser = setting.Database.User
	form.DbPasswd = setting.Database.Passwd
	form.DbName = setting.Database.Name
	form.DbPath = setting.Database.Path
	form.DbSchema = setting.Database.Schema
	form.Charset = setting.Database.Charset

	var curDBOption = "MySQL"
	switch setting.Database.Type {
	case "postgres":
		curDBOption = "PostgreSQL"
	case "mssql":
		curDBOption = "MSSQL"
	case "sqlite3":
		if setting.EnableSQLite3 {
			curDBOption = "SQLite3"
		}
	}

	ctx.Data["CurDbOption"] = curDBOption

	// Application general settings
	form.AppName = setting.AppName
	form.RepoRootPath = setting.RepoRootPath
	form.LFSRootPath = setting.LFS.Path

	// Note(unknown): it's hard for Windows users change a running user,
	// 	so just use current one if config says default.
	if setting.IsWindows && setting.RunUser == "git" {
		form.RunUser = user.CurrentUsername()
	} else {
		form.RunUser = setting.RunUser
	}

	form.Domain = setting.Domain
	form.SSHPort = setting.SSH.Port
	form.HTTPPort = setting.HTTPPort
	form.AppURL = setting.AppURL
	form.LogRootPath = setting.LogRootPath

	// E-mail service settings
	if setting.MailService != nil {
		form.SMTPHost = setting.MailService.Host
		form.SMTPFrom = setting.MailService.From
		form.SMTPUser = setting.MailService.User
	}
	form.RegisterConfirm = setting.Service.RegisterEmailConfirm
	form.MailNotify = setting.Service.EnableNotifyMail

	// Server and other services settings
	form.OfflineMode = setting.OfflineMode
	form.DisableGravatar = setting.DisableGravatar
	form.EnableFederatedAvatar = setting.EnableFederatedAvatar
	form.EnableOpenIDSignIn = setting.Service.EnableOpenIDSignIn
	form.EnableOpenIDSignUp = setting.Service.EnableOpenIDSignUp
	form.DisableRegistration = setting.Service.DisableRegistration
	form.AllowOnlyExternalRegistration = setting.Service.AllowOnlyExternalRegistration
	form.EnableCaptcha = setting.Service.EnableCaptcha
	form.RequireSignInView = setting.Service.RequireSignInView
	form.DefaultKeepEmailPrivate = setting.Service.DefaultKeepEmailPrivate
	form.DefaultAllowCreateOrganization = setting.Service.DefaultAllowCreateOrganization
	form.DefaultEnableTimetracking = setting.Service.DefaultEnableTimetracking
	form.NoReplyAddress = setting.Service.NoReplyAddress
	form.PasswordAlgorithm = setting.PasswordHashAlgo

	middleware.AssignForm(form, ctx.Data)
	ctx.HTML(http.StatusOK, tplInstall)
}

// InstallPost response for submit install items
func InstallPost(ctx *context.Context) {
	form := *web.GetForm(ctx).(*forms.InstallForm)
	var err error
	ctx.Data["CurDbOption"] = form.DbType

	if ctx.HasError() {
		if ctx.HasValue("Err_SMTPUser") {
			ctx.Data["Err_SMTP"] = true
		}
		if ctx.HasValue("Err_AdminName") ||
			ctx.HasValue("Err_AdminPasswd") ||
			ctx.HasValue("Err_AdminEmail") {
			ctx.Data["Err_Admin"] = true
		}

		ctx.HTML(http.StatusOK, tplInstall)
		return
	}

	if _, err = exec.LookPath("git"); err != nil {
		ctx.RenderWithErr(ctx.Tr("install.test_git_failed", err), tplInstall, &form)
		return
	}

	// Pass basic check, now test configuration.
	// Test database setting.

	setting.Database.Type = setting.GetDBTypeByName(form.DbType)
	setting.Database.Host = form.DbHost
	setting.Database.User = form.DbUser
	setting.Database.Passwd = form.DbPasswd
	setting.Database.Name = form.DbName
	setting.Database.Schema = form.DbSchema
	setting.Database.SSLMode = form.SSLMode
	setting.Database.Charset = form.Charset
	setting.Database.Path = form.DbPath

	setting.PasswordHashAlgo = form.PasswordAlgorithm

	if (setting.Database.Type == "sqlite3") &&
		len(setting.Database.Path) == 0 {
		ctx.Data["Err_DbPath"] = true
		ctx.RenderWithErr(ctx.Tr("install.err_empty_db_path"), tplInstall, &form)
		return
	}

	// Set test engine.
	if err = models.NewTestEngine(); err != nil {
		if strings.Contains(err.Error(), `Unknown database type: sqlite3`) {
			ctx.Data["Err_DbType"] = true
			ctx.RenderWithErr(ctx.Tr("install.sqlite3_not_available", "https://docs.gitea.io/en-us/install-from-binary/"), tplInstall, &form)
		} else {
			ctx.Data["Err_DbSetting"] = true
			ctx.RenderWithErr(ctx.Tr("install.invalid_db_setting", err), tplInstall, &form)
		}
		return
	}

	// Test repository root path.
	form.RepoRootPath = strings.ReplaceAll(form.RepoRootPath, "\\", "/")
	if err = os.MkdirAll(form.RepoRootPath, os.ModePerm); err != nil {
		ctx.Data["Err_RepoRootPath"] = true
		ctx.RenderWithErr(ctx.Tr("install.invalid_repo_path", err), tplInstall, &form)
		return
	}

	// Test LFS root path if not empty, empty meaning disable LFS
	if form.LFSRootPath != "" {
		form.LFSRootPath = strings.ReplaceAll(form.LFSRootPath, "\\", "/")
		if err := os.MkdirAll(form.LFSRootPath, os.ModePerm); err != nil {
			ctx.Data["Err_LFSRootPath"] = true
			ctx.RenderWithErr(ctx.Tr("install.invalid_lfs_path", err), tplInstall, &form)
			return
		}
	}

	// Test log root path.
	form.LogRootPath = strings.ReplaceAll(form.LogRootPath, "\\", "/")
	if err = os.MkdirAll(form.LogRootPath, os.ModePerm); err != nil {
		ctx.Data["Err_LogRootPath"] = true
		ctx.RenderWithErr(ctx.Tr("install.invalid_log_root_path", err), tplInstall, &form)
		return
	}

	currentUser, match := setting.IsRunUserMatchCurrentUser(form.RunUser)
	if !match {
		ctx.Data["Err_RunUser"] = true
		ctx.RenderWithErr(ctx.Tr("install.run_user_not_match", form.RunUser, currentUser), tplInstall, &form)
		return
	}

	// Check logic loophole between disable self-registration and no admin account.
	if form.DisableRegistration && len(form.AdminName) == 0 {
		ctx.Data["Err_Services"] = true
		ctx.Data["Err_Admin"] = true
		ctx.RenderWithErr(ctx.Tr("install.no_admin_and_disable_registration"), tplInstall, form)
		return
	}

	// Check admin user creation
	if len(form.AdminName) > 0 {
		// Ensure AdminName is valid
		if err := models.IsUsableUsername(form.AdminName); err != nil {
			ctx.Data["Err_Admin"] = true
			ctx.Data["Err_AdminName"] = true
			if models.IsErrNameReserved(err) {
				ctx.RenderWithErr(ctx.Tr("install.err_admin_name_is_reserved"), tplInstall, form)
				return
			} else if models.IsErrNamePatternNotAllowed(err) {
				ctx.RenderWithErr(ctx.Tr("install.err_admin_name_pattern_not_allowed"), tplInstall, form)
				return
			}
			ctx.RenderWithErr(ctx.Tr("install.err_admin_name_is_invalid"), tplInstall, form)
			return
		}
		// Check Admin email
		if len(form.AdminEmail) == 0 {
			ctx.Data["Err_Admin"] = true
			ctx.Data["Err_AdminEmail"] = true
			ctx.RenderWithErr(ctx.Tr("install.err_empty_admin_email"), tplInstall, form)
			return
		}
		// Check admin password.
		if len(form.AdminPasswd) == 0 {
			ctx.Data["Err_Admin"] = true
			ctx.Data["Err_AdminPasswd"] = true
			ctx.RenderWithErr(ctx.Tr("install.err_empty_admin_password"), tplInstall, form)
			return
		}
		if form.AdminPasswd != form.AdminConfirmPasswd {
			ctx.Data["Err_Admin"] = true
			ctx.Data["Err_AdminPasswd"] = true
			ctx.RenderWithErr(ctx.Tr("form.password_not_match"), tplInstall, form)
			return
		}
	}

	if form.AppURL[len(form.AppURL)-1] != '/' {
		form.AppURL += "/"
	}

	// Save settings.
	cfg := ini.Empty()
	isFile, err := util.IsFile(setting.CustomConf)
	if err != nil {
		log.Error("Unable to check if %s is a file. Error: %v", setting.CustomConf, err)
	}
	if isFile {
		// Keeps custom settings if there is already something.
		if err = cfg.Append(setting.CustomConf); err != nil {
			log.Error("Failed to load custom conf '%s': %v", setting.CustomConf, err)
		}
	}
	cfg.Section("database").Key("DB_TYPE").SetValue(setting.Database.Type)
	cfg.Section("database").Key("HOST").SetValue(setting.Database.Host)
	cfg.Section("database").Key("NAME").SetValue(setting.Database.Name)
	cfg.Section("database").Key("USER").SetValue(setting.Database.User)
	cfg.Section("database").Key("PASSWD").SetValue(setting.Database.Passwd)
	cfg.Section("database").Key("SCHEMA").SetValue(setting.Database.Schema)
	cfg.Section("database").Key("SSL_MODE").SetValue(setting.Database.SSLMode)
	cfg.Section("database").Key("CHARSET").SetValue(setting.Database.Charset)
	cfg.Section("database").Key("PATH").SetValue(setting.Database.Path)
	cfg.Section("database").Key("LOG_SQL").SetValue("false") // LOG_SQL is rarely helpful

	cfg.Section("").Key("APP_NAME").SetValue(form.AppName)
	cfg.Section("repository").Key("ROOT").SetValue(form.RepoRootPath)
	cfg.Section("").Key("RUN_USER").SetValue(form.RunUser)
	cfg.Section("server").Key("SSH_DOMAIN").SetValue(form.Domain)
	cfg.Section("server").Key("DOMAIN").SetValue(form.Domain)
	cfg.Section("server").Key("HTTP_PORT").SetValue(form.HTTPPort)
	cfg.Section("server").Key("ROOT_URL").SetValue(form.AppURL)

	if form.SSHPort == 0 {
		cfg.Section("server").Key("DISABLE_SSH").SetValue("true")
	} else {
		cfg.Section("server").Key("DISABLE_SSH").SetValue("false")
		cfg.Section("server").Key("SSH_PORT").SetValue(fmt.Sprint(form.SSHPort))
	}

	if form.LFSRootPath != "" {
		cfg.Section("server").Key("LFS_START_SERVER").SetValue("true")
		cfg.Section("server").Key("LFS_CONTENT_PATH").SetValue(form.LFSRootPath)
		var secretKey string
		if secretKey, err = generate.NewJwtSecret(); err != nil {
			ctx.RenderWithErr(ctx.Tr("install.lfs_jwt_secret_failed", err), tplInstall, &form)
			return
		}
		cfg.Section("server").Key("LFS_JWT_SECRET").SetValue(secretKey)
	} else {
		cfg.Section("server").Key("LFS_START_SERVER").SetValue("false")
	}

	if len(strings.TrimSpace(form.SMTPHost)) > 0 {
		cfg.Section("mailer").Key("ENABLED").SetValue("true")
		cfg.Section("mailer").Key("HOST").SetValue(form.SMTPHost)
		cfg.Section("mailer").Key("FROM").SetValue(form.SMTPFrom)
		cfg.Section("mailer").Key("USER").SetValue(form.SMTPUser)
		cfg.Section("mailer").Key("PASSWD").SetValue(form.SMTPPasswd)
	} else {
		cfg.Section("mailer").Key("ENABLED").SetValue("false")
	}
	cfg.Section("service").Key("REGISTER_EMAIL_CONFIRM").SetValue(fmt.Sprint(form.RegisterConfirm))
	cfg.Section("service").Key("ENABLE_NOTIFY_MAIL").SetValue(fmt.Sprint(form.MailNotify))

	cfg.Section("server").Key("OFFLINE_MODE").SetValue(fmt.Sprint(form.OfflineMode))
	cfg.Section("picture").Key("DISABLE_GRAVATAR").SetValue(fmt.Sprint(form.DisableGravatar))
	cfg.Section("picture").Key("ENABLE_FEDERATED_AVATAR").SetValue(fmt.Sprint(form.EnableFederatedAvatar))
	cfg.Section("openid").Key("ENABLE_OPENID_SIGNIN").SetValue(fmt.Sprint(form.EnableOpenIDSignIn))
	cfg.Section("openid").Key("ENABLE_OPENID_SIGNUP").SetValue(fmt.Sprint(form.EnableOpenIDSignUp))
	cfg.Section("service").Key("DISABLE_REGISTRATION").SetValue(fmt.Sprint(form.DisableRegistration))
	cfg.Section("service").Key("ALLOW_ONLY_EXTERNAL_REGISTRATION").SetValue(fmt.Sprint(form.AllowOnlyExternalRegistration))
	cfg.Section("service").Key("ENABLE_CAPTCHA").SetValue(fmt.Sprint(form.EnableCaptcha))
	cfg.Section("service").Key("REQUIRE_SIGNIN_VIEW").SetValue(fmt.Sprint(form.RequireSignInView))
	cfg.Section("service").Key("DEFAULT_KEEP_EMAIL_PRIVATE").SetValue(fmt.Sprint(form.DefaultKeepEmailPrivate))
	cfg.Section("service").Key("DEFAULT_ALLOW_CREATE_ORGANIZATION").SetValue(fmt.Sprint(form.DefaultAllowCreateOrganization))
	cfg.Section("service").Key("DEFAULT_ENABLE_TIMETRACKING").SetValue(fmt.Sprint(form.DefaultEnableTimetracking))
	cfg.Section("service").Key("NO_REPLY_ADDRESS").SetValue(fmt.Sprint(form.NoReplyAddress))

	cfg.Section("").Key("RUN_MODE").SetValue("prod")

	cfg.Section("session").Key("PROVIDER").SetValue("file")

	cfg.Section("log").Key("MODE").SetValue("console")
	cfg.Section("log").Key("LEVEL").SetValue(setting.LogLevel.String())
	cfg.Section("log").Key("ROOT_PATH").SetValue(form.LogRootPath)
	cfg.Section("log").Key("ROUTER").SetValue("console")

	cfg.Section("security").Key("INSTALL_LOCK").SetValue("true")
	var secretKey string
	if secretKey, err = generate.NewSecretKey(); err != nil {
		ctx.RenderWithErr(ctx.Tr("install.secret_key_failed", err), tplInstall, &form)
		return
	}
	cfg.Section("security").Key("SECRET_KEY").SetValue(secretKey)
	if len(form.PasswordAlgorithm) > 0 {
		cfg.Section("security").Key("PASSWORD_HASH_ALGO").SetValue(form.PasswordAlgorithm)
	}

	err = os.MkdirAll(filepath.Dir(setting.CustomConf), os.ModePerm)
	if err != nil {
		ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form)
		return
	}

	if err = cfg.SaveTo(setting.CustomConf); err != nil {
		ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form)
		return
	}

	// Re-read settings
	PostInstallInit(ctx)

	// Create admin account
	if len(form.AdminName) > 0 {
		u := &models.User{
			Name:     form.AdminName,
			Email:    form.AdminEmail,
			Passwd:   form.AdminPasswd,
			IsAdmin:  true,
			IsActive: true,
		}
		if err = models.CreateUser(u); err != nil {
			if !models.IsErrUserAlreadyExist(err) {
				setting.InstallLock = false
				ctx.Data["Err_AdminName"] = true
				ctx.Data["Err_AdminEmail"] = true
				ctx.RenderWithErr(ctx.Tr("install.invalid_admin_setting", err), tplInstall, &form)
				return
			}
			log.Info("Admin account already exist")
			u, _ = models.GetUserByName(u.Name)
		}

		days := 86400 * setting.LogInRememberDays
		ctx.SetCookie(setting.CookieUserName, u.Name, days)

		ctx.SetSuperSecureCookie(base.EncodeMD5(u.Rands+u.Passwd),
			setting.CookieRememberName, u.Name, days)

		// Auto-login for admin
		if err = ctx.Session.Set("uid", u.ID); err != nil {
			ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form)
			return
		}
		if err = ctx.Session.Set("uname", u.Name); err != nil {
			ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form)
			return
		}

		if err = ctx.Session.Release(); err != nil {
			ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form)
			return
		}
	}

	log.Info("First-time run install finished!")

	ctx.Flash.Success(ctx.Tr("install.install_success"))

	ctx.Header().Add("Refresh", "1; url="+setting.AppURL+"user/login")
	ctx.HTML(http.StatusOK, tplPostInstall)

	// Now get the http.Server from this request and shut it down
	// NB: This is not our hammerable graceful shutdown this is http.Server.Shutdown
	srv := ctx.Value(http.ServerContextKey).(*http.Server)
	go func() {
		if err := srv.Shutdown(graceful.GetManager().HammerContext()); err != nil {
			log.Error("Unable to shutdown the install server! Error: %v", err)
		}
	}()
}


text:
- Unify `Relay` naming around `nodes` as the items of a connection:
  - `Relay::BaseConnection.connection_for_nodes` replaces `Relay::BaseConnection.connection_for_items`
  - `Relay::BaseConnection#nodes` replaces `Relay::BaseConnection#object`

### New features

- Connection fields' `.resolve_proc` is an instance of `Relay::ConnectionResolve` #204
- Types, fields and arguments can store arbitrary values in their `metadata` hashes #203

## 0.18.0 (4 Aug 2016)

### Breaking changes

- `graphql-relay` has been merged with `graphql`, you should remove `graphql-relay` from your gemfile. #195

### Deprecations

### New features

- `GraphQL.parse` can turn schema definitions into a `GraphQL::Language::Nodes::Document`. The document can be stringified again with `Document#to_query_string` #191
- Validation errors include a `path` to the part of the query where the error was found #198
- `.define` also accepts keywords for each helper method, eg `GraphQL::ObjectType.define(name: "PostType", ...)`

### Bug fixes

- `global_id_field`s have default complexity of 1, not `nil`
- Relay `pageInfo` is correct for connections limited by `max_page_size`
- Rescue invalid variable errors & missing operation name errors during query analysis

## 0.17.2 (26 Jul 2016)

### Bug fixes

- Correctly spread fragments when nested inside other fragments #194

## 0.17.1 (26 Jul 2016)

### Bug fixes

- Fix `InternalRepresentation::Node#inspect`

## 0.17.0 (21 Jul 2016)

### Breaking changes

- `InternalRepresentation::Node` API changes:

  - `#definition_name` returns the field name on field nodes (while `#name` may have an alias)
  - `#definitions` returns `{type => field}` pairs for possible fields on this node
  - `#definition` is gone, it is equivalent to `node.definitions.values.first`
  - `#on_types` is gone, it is equivalent to `node.definitions.keys`

### New features

- Accept `hash_key:` field option
- Call `.define { }` block lazily, so `-> { }` is not needed for circular references #182

### Bug fixes

- Support `on` as an Enum value
- If the same field is requested on multiple types, choose the maximum complexity among them (not the first)

## 0.16.1 (20 Jul 2016)

### Bug fixes

- Fix merging fragments on Union types (see #190, broken from #180)

## 0.16.0 (14 Jul 2016)

### Breaking changes & deprecations

- I don't _know_ that this breaks anything, but  `GraphQL::Query::SerialExecution` now iterates over a tree of `GraphQL::InternalRepresentation::Node`s instead of an AST (`GraphQL::Language::Nodes::Document`).

### New features

- Query context keys can be assigned with `Context#[]=` #178
- Cancel further field resolution with `TimeoutMiddleware` #179
- Add `GraphQL::InternalRepresentation` for normalizing queries from AST #180
- Analyze the query before running it #180
- Assign complexity cost to fields, enforce max complexity before running it #180
- Log max complexity or max depth with `MaxComplexity` or `MaxDepth` analyzers #180
- Query context exposes `#irep_node`, the internal representation of the current node #180

### Bug fixes

- Non-null errors are propagated to the next nullable field, all the way up to `data` #174

## 0.15.3 (28 Jun 2016)

### New features

- `EnumValue`s can receive their properties after instantiation #171

## 0.15.2 (16 Jun 2016)

### New features

- Support lazy type arguments in Object's `interfaces` and Union's `possible_types` #169

### Bug fixes

- Support single-member Unions, as per the spec #170

## 0.15.1 (15 Jun 2016)

### Bug fixes

- Whitelist operation types in `lexer.rb`

## 0.15.0 (11 Jun 2016)

### Breaking changes & deprecations

- Remove `debug:` option, propagate all errors. #161

## 0.14.1 (11 Jun 2016)

### Breaking changes & deprecations

- `debug:` is deprecated (#165). Propagating errors (`debug: true`) will become the default behavior. You can get a similar implementation of error gobbling with `CatchallMiddleware`. Add it to your schema:

    ```ruby
    MySchema.middleware << GraphQL::Schema::CatchallMiddleware
    ```

### New features

### Bug fixes

- Restore previous introspection fields on DirectiveType as deprecated #164
- Apply coercion to input default values #162
- Proper Enum behavior when a value isn't found

## 0.14.0 (31 May 2016)

### Breaking changes & deprecations

### New features

- `GraphQL::Language::Nodes::Document#to_query_string` will re-serialize a query AST #151
- Accept `root_value:` when running a query #157
- Accept a `GraphQL::Language::Nodes::Document` to `Query.new` (this allows you to cache parsed queries on the server) #152

### Bug fixes

- Improved parse error messages #149
- Improved build-time validation #150
- Raise a meaningful error when a Union or Interface can't be resolved during query execution #155

## 0.13.0 (29 Apr 2016)

### Breaking changes & deprecations

- "Dangling" object types are not loaded into the schema. The must be passed in `GraphQL::Schema.new(types: [...])`. (This was deprecated in 0.12.1)

### New features

- Update directive introspection to new spec #121
- Improved schema validation errors #113
- 20x faster parsing #119
- Support inline fragments without type condition #123
- Support multiple schemas composed of the same types #142
- Accept argument `description` and `default_value` in the block #138
- Middlewares can send _new_ arguments to subsequent middlewares #129

### Bug fixes

- Don't leak details of internal errors #120
- Default query `context` to `{}` #133
- Fixed list nullability validation #131
- Ensure field names are strings #128
- Fix `@skip` and `@include` implementation #124
- Interface membership is not shared between schemas #142

## 0.12.1 (26 Apr 2016)

### Breaking changes & deprecations

- __Connecting object types to the schema _only_ via interfaces is deprecated.__ It will be unsupported in the next version of `graphql`.

  Sometimes, object type is only connected to the Query (or Mutation) root by being a member of an interface. In these cases, bugs happen, especially with Rails development mode. (And sometimes, the bugs don't appear until you deploy to a production environment!)

  So, in a case like this:

  ```ruby
  HatInterface = GraphQL::ObjectType.define do
    # ...
  end

  FezType = GraphQL::ObjectType.define do
    # ...
    interfaces [HatInterface]
  end

  QueryType = GraphQL::ObjectType.define do
    field :randomHat, HatInterface # ...
  end
  ```

  `FezType` can only be discovered by `QueryType` _through_ `HatInterface`. If `fez_type.rb` hasn't been loaded by Rails, `HatInterface.possible_types` will be empty!

  Now, `FezType` must be passed to the schema explicitly:

  ```ruby
  Schema.new(
    # ...
    types: [FezType]
  )
  ```

  Since the type is passed directly to the schema, it will be loaded right away!

### New features

### Bug fixes

## 0.12.0 (20 Mar 2016)

### Breaking changes & deprecations

- `GraphQL::DefinitionConfig` was replaced by `GraphQL::Define` #116
- Many scalar types are more picky about which inputs they allow (#115). To get the previous behavior, add this to your program:

  ```ruby
  # Previous coerce behavior for scalars:
  GraphQL::BOOLEAN_TYPE.coerce = -> (value) { !!value }
  GraphQL::ID_TYPE.coerce = -> (value) { value.to_s }
  GraphQL::STRING_TYPE.coerce = ->  (value) { value.to_s }
  # INT_TYPE and FLOAT_TYPE were unchanged
  ```

- `GraphQL::Field`s can't be renamed because `#resolve` may depend on that name. (This was only a problem if you pass the _same_ `GraphQL::Field` instance to `field ... field:` definitions.)
- `GraphQL::Query::DEFAULT_RESOLVE` was removed. `GraphQL::Field#resolve` handles that behavior.

### New features

- Can override `max_depth:` from `Schema#execute`
- Base `GraphQL::Error` for all graphql-related errors

### Bug fixes

- Include `""` for String default values (so it's encoded as a GraphQL string literal)

## 0.11.1 (6 Mar 2016)

### New features

- Schema `max_depth:` option #110
- Improved validation errors for input objects #104
- Interfaces provide field implementations to object types #108

## 0.11.0 (28 Feb 2016)

### Breaking changes & deprecations

- `GraphQL::Query::BaseExecution` was removed, you should probably extend `SerialExecution` instead #96
- `GraphQL::Language::Nodes` members no longer raise if they don't get inputs during `initialize` #92
- `GraphQL.parse` no longer accepts `as:` for parsing partial queries.  #92

### New features

- `Field#property` & `Field#property=` can be used to access & modify the method that will be sent to the underlying object when resolving a field #88
- When defining a field, you can pass a string for as `type`. It will be looked up in the global namespace.
- `Query::Arguments#to_h` unwraps `Arguments` objects recursively
- If you raise `GraphQL::ExecutionError` during field resolution, it will be rescued and the message will be added to the response's `errors` key. #93
- Raise an error when non-null fields are `nil` #94

### Bug fixes

- Accept Rails params as input objects
- Don't get a runtime error when input contains unknown key #100

## 0.10.9 (15 Jan 2016)

### Bug fixes

- Handle re-assignment of `ObjectType#interfaces` #84
- Fix merging queries on interface-typed fields #85

## 0.10.8 (14 Jan 2016)

### Bug fixes

- Fix transform of nested lists #79
- Fix parse & transform of escaped characters #83

## 0.10.7 (22 Dec 2015)

### New features

- Support Rubinius

### Bug fixes

- Coerce values into one-item lists for ListTypes

## 0.10.6 (20 Dec 2015)

### Bug fixes

- Remove leftover `puts`es

## 0.10.5 (19 Dec 2015)

### Bug fixes

- Accept enum value description in definition #71
- Correctly parse empty input objects #75
- Correctly parse arguments preceded by newline
- Find undefined input object keys during static validation

## 0.10.4 (24 Nov 2015)

### New features

- Add `Arguments#to_h` #66

### Bug fixes

- Accept argument description in definition
- Correctly parse empty lists

## 0.10.3 (11 Nov 2015)

### New features

- Support root-level `subscription` type

### Bug fixes

- Require Set for Schema::Printer

## 0.10.2 (10 Nov 2015)

### Bug fixes

- Handle blank strings in queries
- Raise if a field is configured without a proper type #61

## 0.10.1 (22 Oct 2015)

### Bug fixes

- Properly merge fields on fragments within fragments
- Properly delegate enumerable-ish methods on `Arguments` #56
- Fix & refactor literal coersion & validation #53

## 0.10.0 (17 Oct 2015)

### New features

- Scalars can have distinct `coerce_input` and `coerce_result` methods #48
- Operations don't require a name #54

### Bug fixes

- Big refactors and fixes to variables and arguments:
  - Correctly apply argument default values
  - Correctly apply variable default values
  - Raise at execution-time if non-null variables are missing
  - Incoming values are coerced to their proper types before execution

## 0.9.5 (1 Oct 2015)

### New features

- Add `Schema#middleware` to wrap field access
- Add `RescueMiddleware` to handle errors during field execution
- Add `Schema::Printer` for printing the schema definition #45

### Bug fixes

## 0.9.4 (22 Sept 2015)

### New features

- Fields can return `GraphQL::ExecutionError`s to add errors to the response

### Bug fixes

- Fix resolution of union types in some queries #41

## 0.9.3 (15 Sept 2015)

### New features

- Add `Schema#execute` shorthand for running queries
- Merge identical fields in fragments so they're only resolved once #34
- An error during parsing raises `GraphQL::ParseError`  #33

### Bug fixes

- Find nested input types in `TypeReducer` #35
- Find variable usages inside fragments during static validation

## 0.9.2, 0.9.1 (10 Sept 2015)

### Bug fixes

- remove Celluloid dependency

## 0.9.0 (10 Sept 2015)

### Breaking changes & deprecations

- remove `GraphQL::Query::ParallelExecution` (use [`graphql-parallel`](https://github.com/rmosolgo/graphql-parallel))

## 0.8.1 (10 Sept 2015)

### Breaking changes & deprecations

- `GraphQL::Query::ParallelExecution` has been extracted to [`graphql-parallel`](https://github.com/rmosolgo/graphql-parallel)

## 0.8.0 (4 Sept 2015)

### New features

- Async field resolution with `context.async { ... }`
- Access AST node during resolve with `context.ast_node`

### Bug fixes

- Fix for validating arguments returning up too soon
- Raise if you try to define 2 types with the same name
- Raise if you try to get a type by name but it doesn't exist

## 0.7.1 (27 Aug 2015)

### Bug fixes

- Merge nested results from different fragments instead of using the latest one only

## 0.7.0 (26 Aug 2015)

### Breaking changes & deprecations

- Query keyword argument `params:` was removed, use `variables:` instead.

### Bug fixes

- `@skip` has precedence over `@include`
- Handle when `DEFAULT_RESOVE` returns nil

## 0.6.2 (20 Aug 2015)

### Bug fixes

- Fix whitespace parsing in input objects

## 0.6.1 (16 Aug 2015)

### New features

- Parse UTF-8 characters & escaped characters

### Bug fixes

- Properly parse empty strings
- Fix argument / variable compatibility validation

## 0.6.0 (14 Aug 2015)

### Breaking changes & deprecations

- Deprecate `params` option to `Query#new` in favor of `variables`
- Deprecated `.new { |obj, types, fields, args| }` API was removed (use `.define`)

### New features

- `Query#new` accepts `operation_name` argument
- `InterfaceType` and `UnionType` accept `resolve_type` configs

### Bug fixes

- Gracefully handle blank-string & whitespace-only queries
- Handle lists in variable definitions and arguments
- Handle non-null input types

## 0.5.0 (12 Aug 2015)

### Breaking changes & deprecations

- Deprecate definition API that yielded a bunch of helpers #18

### New features

- Add new definition API #18

redpajama_set_name: RedPajamaGithub


text:
/** Javascript cases (in switch statements) can contain arbitrary expressions,
 * whereas the C11 standard requires they be integer constant expressions.
 * This pass transforms switch statements with non-integer constant expressions
 * in their case statements into nested if statements.
 *
 * @author Cole Schlesinger (cschles1@gmail.com)
 */
package com.samsung.sjs.backend;

import java.util.*;
import com.samsung.sjs.backend.asts.ir.*;
import com.samsung.sjs.CompilerOptions;
import com.samsung.sjs.types.Type;
import com.samsung.sjs.types.BooleanType;

public class SwitchDesugaringPass extends IRTransformer {

    protected final CompilerOptions options;
    protected final Script script;
    private Stack<Boolean> switchStack;

    /** Build a traversal object.
     *  @param opts compiler options
     *  @param s    script to be traversed
     */
    public SwitchDesugaringPass(CompilerOptions opts, Script s) {
        super(s);
        this.options = opts;
        this.script = s;
        this.switchStack = new Stack<Boolean>();
    }

    /** Traverse the script given to the constructor.
     *  @return the desugared script
     */
    public Script convert() {
        return (Script) script.accept(this);
    }

    private boolean desugaringSwitch() {
        if (switchStack.isEmpty()) {
            return false;
        }
        return switchStack.peek().booleanValue();
    }

    /** Determine whether an expression contains only integer and character
     * constants and has an integer type.
     *
     * The C11 standard requires that expressions in switch case statements be
     * integer constant expressions.  C11 defines other valid operands, such as
     * sizeof(), which aren't exposed in Javascript.
     *
     * Note that this is subtly different than Expression.isPure(), which
     * simply checks whether an expression is (extensionally) pure, and
     * Expression.isConst(), which can include non-integer constants.  This
     * traversal is more strict: it requires that operands be (C-style)
     * integers, not, say, floats.
     */
    private class IsIntegerConstantExpression extends VoidIRVisitor {

        private boolean isConstant;

        /** Return {@code true} if {@code node} is an integer constant
         * expression and {@code false} otherwise.
         */
        public boolean check(Expression node) {
            // Assume an expression is an integer constant expression until the
            // traversal discover otherwise.
            this.isConstant = true;
            node.accept(this);
            return this.isConstant;
        }

        @Override
        public Void visitAllocArrayLiteral(AllocArrayLiteral node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitAllocClosure(AllocClosure node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitAllocMapLiteral(AllocMapLiteral node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitAllocNewObject(AllocNewObject node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitAllocObjectLiteral(AllocObjectLiteral node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitArrayIndex(ArrayIndex node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitCondExpr(CondExpr node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitFieldAssignment(FieldAssignment node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitPredictedFieldAssignment(PredictedFieldAssignment node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitFieldRead(FieldRead node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitPredictedFieldRead(PredictedFieldRead node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitFloatLiteral(FloatLiteral node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitFunction(Function node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitFunctionCall(FunctionCall node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitIntrinsicName(IntrinsicName node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitLambda(Lambda node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitLetIn(LetIn node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitMethodCall(MethodCall node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitNamedLambda(NamedLambda node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitStr(Str node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitThisLiteral(ThisLiteral node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitUndef(Undefined node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitVar(Var node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitVarAssignment(VarAssignment node) {
            this.isConstant = false;
            return null;
        }

        @Override
        public Void visitBinaryOp(BinaryOp node) {
            switch (node.getOp()) {
                case "+":
                case "-":
                case "*":
                case "/":
                case "%":
                case "&&":
                case "||":
                case ">>":
                case ">>>":
                case "<<":
                    return super.visitBinaryOp(node);
                default:
                    this.isConstant = false;
                    return null;
            }
        }

        @Override
        public Void visitUnaryOp(UnaryOp node) {
            switch (node.getOp()) {
                case "-":
                    return super.visitUnaryOp(node);
                default:
                    this.isConstant = false;
                    return null;
            }
        }
    }

    /** Traverse each statement, replacing switch statements where necessary,
     * and packaging the resulting statements into a Block.
     */
    private Block traverseAndWrap(List<Statement> statements) {

        // TODO(cns): what if the list is empty?  Is there a nop statement we
        // should insert here?
        Block body = new Block();
        for (Statement s : statements) {
            if (s instanceof Break) {
                continue;
            }
            Statement desugaredStatement = (Statement) s.accept(this);
            body.addStatement(desugaredStatement);
        }
        return body;
    }

    private IRNode mkIfOfSwitch(Switch node) {
        Statement rv = null;
        Expression discriminee = node.getDiscriminee();
        List<Case> cases = node.getCases();

        // If a default case exists, initialize rv with it and remove it from
        // the list.
        for (Case c : cases) {
            if (c.getValue() == null) {
                rv = traverseAndWrap(c.getStatements());
                cases.remove(c);
                break;
            }
        }

        // Build the if statement from the inside out.
        for (int i = cases.size() - 1; i >= 0; i--) {
            Case c = cases.get(i);
            BinaryOp test = new BinaryOp(discriminee, "==", c.getValue());
            test.setType(BooleanType.make());

            rv = new IfThenElse(
                test,
                traverseAndWrap(c.getStatements()),
                rv);

        }
        return rv;
    }

    @Override public IRNode visitBreak(Break b) {
        if (desugaringSwitch())
            // Replace break statements with an empty block (i.e. a nop) in
            // switch statements that are being desugared.
            return IRManipulator.mkBlock();
        else
            return super.visitBreak(b);
    }

    @Override
    public IRNode visitSwitch(Switch node) {
        // Check whether all cases are integer constant expressions.
        IRNode rv;
        boolean hasConstCases = true;
        IsIntegerConstantExpression checker =
          new IsIntegerConstantExpression();
        for (Case c : node.getCases()) {
            Expression val = c.getValue();
            if (val == null) {
                // NB: Case encodes "default" as a null value.
                continue;
            }
            else if (!checker.check(val)) {
                hasConstCases = false;
                break;
            }
        }
        if (hasConstCases) {
            // Leave as switch.
            this.switchStack.push(Boolean.FALSE);
            rv = super.visitSwitch(node);
            this.switchStack.pop();
        } else {
            // Transform to if.
            this.switchStack.push(Boolean.TRUE);
            rv = mkIfOfSwitch(node);
            this.switchStack.pop();
        }

        return rv;
    }
}


text:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Root>
  <ResponseStatus>
    <Status>OK</Status>
    <TimeStamp>1.10.2009 16:03:24</TimeStamp>
  </ResponseStatus>
  <SalesPaymentList>
    <SalesPayment>
      <NetvisorKey>165</NetvisorKey>
      <Name>Matti Mallikas</Name>
      <Date>7.2.2014</Date>
      <Sum>249,90</Sum>
      <ReferenceNumber>1094</ReferenceNumber>
      <ForeignCurrencyAmount/>
      <InvoiceNumber>1</InvoiceNumber>
      <BankStatus>FAILED</BankStatus>
      <BankStatusErrorDescription code="ERROR_IN_DUE_DATE">Eräpäivä virheellinen</BankStatusErrorDescription>
    </SalesPayment>
    <SalesPayment>
      <NetvisorKey>166</NetvisorKey>
      <Name>Assi Asiakas</Name>
      <Date>10.3.2014</Date>
      <Sum>200</Sum>
      <ReferenceNumber>1106</ReferenceNumber>
      <ForeignCurrencyAmount/>
      <InvoiceNumber>2</InvoiceNumber>
      <BankStatus>OK</BankStatus>
    </SalesPayment>
  </SalesPaymentList>
</Root>


text:
FROM debian:11 AS downloader

WORKDIR /opt

RUN apt-get update && \
    apt-get install tree curl xz-utils -y && \
    rm -rf /var/lib/apt/lists/*

RUN mkdir /opt/ffmpeg && \
    curl -qsSL https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz | tar xJv -C /opt/ffmpeg --strip-components 1

RUN mkdir /opt/youtube-dl && \
    ## Youtube DL Installation
    curl -qsSL https://yt-dl.org/downloads/latest/youtube-dl -o /opt/youtube-dl/youtube-dl && chmod +x /opt/youtube-dl/youtube-dl

RUN mkdir /opt/yt-dl && \
    curl -qsSL https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /opt/yt-dl/yt-dlp && \
    chmod a+rx /opt/yt-dl/yt-dlp && \
    ## Final check
    tree /opt/

FROM openjdk:17-slim as base-image
RUN apt-get update && apt-get install python3 rtmpdump procps -y --no-install-recommends && \
      rm -rf /var/lib/apt/lists/* && \
      apt-get autoremove && \
      ln -s /usr/bin/python3 /usr/bin/python

ENV PATH="/opt/ffmpeg:/opt/youtube-dl/:/opt/yt-dl/:${PATH}"
COPY --from=downloader /opt/ /opt/

RUN ffmpeg -version | head -n 1 && \
    youtube-dl --version && \
    yt-dlp --version && \
    rtmpdump --help 2>&1 | head -n 1

ENV PODCASTSERVER_EXTERNALTOOLS_FFMPEG    "/opt/ffmpeg/ffmpeg"
ENV PODCASTSERVER_EXTERNALTOOLS_FFPROBE   "/opt/ffmpeg/ffprobe"
ENV PODCASTSERVER_EXTERNALTOOLS_RTMPDUMP  "/usr/bin/rtmpdump"
ENV PODCASTSERVER_EXTERNALTOOLS_YOUTUBEDL "/opt/yt-dl/yt-dlp"


text:
namespace fst {
namespace script {

using CompileStringInnerArgs =
    std::tuple<const string &, MutableFstClass *, StringTokenType,
               const SymbolTable *, const WeightClass &, bool>;

using CompileStringArgs = WithReturnValue<bool, CompileStringInnerArgs>;

template <class Arc>
void CompileString(CompileStringArgs *args) {
  MutableFst<Arc> *fst = std::get<1>(args->args)->GetMutableFst<Arc>();
  const typename Arc::Weight weight =
      *(std::get<4>(args->args).GetWeight<typename Arc::Weight>());
  args->retval =
      CompileString(std::get<0>(args->args), fst, std::get<2>(args->args),
                    std::get<3>(args->args), weight, std::get<5>(args->args));
}

// As is sometimes the case, there are fewer default arguments for the scripting
// API variant because we can't infer the underlying weight type.
bool CompileString(const string &str, MutableFstClass *fst,
                   StringTokenType ttype, const SymbolTable *syms,
                   const WeightClass &weight, bool attach_symbols = true);

}  // namespace script
}  // namespace fst

#endif  // PYNINI_STRINGCOMPILESCRIPT_H_


text:
title <input type="text" [(ngModel)]="task.title" />

date <input type="date" [(ngModel)]="task.due_date" />

    説明

<app-button buttonType="submit" (clickEvent)="register()">登録</app-button>


text:
package com.race604.react.view.swiperefresh.event;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.uimanager.events.Event;
import com.facebook.react.uimanager.events.RCTEventEmitter;

/**
 * Created by Jing on 15/10/1.
 */
public class RefreshEvent extends Event<RefreshEvent> {

    public static final String EVENT_NAME = "topSwipeRefresh";

    public RefreshEvent(int viewTag, long timestampMs) {
        super(viewTag, timestampMs);
    }

    @Override
    public String getEventName() {
        return EVENT_NAME;
    }

    @Override
    public short getCoalescingKey() {
        return 0;
    }

    @Override
    public void dispatch(RCTEventEmitter rctEventEmitter) {
        rctEventEmitter.receiveEvent(getViewTag(), getEventName(), Arguments.createMap());
    }
}


text:
#define _WIN32_WINNT 0x0601 // Windows 7 und höher
#include <windows.h>
#include <stdio.h>
#include <psapi.h>

// gegen folgende Library linken:
#pragma comment(lib, "psapi.lib")
#pragma comment(lib, "advapi32.lib")

// für Microsoft Compiler
#ifdef _MSC_VER
#define strncmpi strnicmp
#endif

// für Borland Compiler
#ifndef NTSTATUS
#define NTSTATUS long
#endif

// 'On Windows Vista, every page of memory has a priority in the range of 0 to 7...'
const DWORD CRITICAL_MEMORY_PRIORITY = 7;
const DWORD HIGH_MEMORY_PRIORITY = 6;
const DWORD NORMAL_MEMORY_PRIORITY = 5;
const DWORD BELOWNORMAL_MEMORY_PRIORITY = 4;
const DWORD LOW_MEMORY_PRIORITY = 3;
const DWORD BELOWLOW_MEMORY_PRIORITY = 2;
const DWORD VERYLOW_MEMORY_PRIORITY = 1;
const DWORD BELOWVERYLOW_MEMORY_PRIORITY = 0;

// I/O Priority	Usage
// 4 - Critical	Memory manager
// 3 - High			Unused
// 2 - Normal		Default priority
// 1 - Low				Default task priority
// 0 - Very low	Background activity
const DWORD CRITICAL_IO_PRIORITY = 4;
const DWORD HIGH_IO_PRIORITY = 3;
const DWORD NORMAL_IO_PRIORITY = 2;
const DWORD LOW_IO_PRIORITY = 1;
const DWORD VERYLOW_IO_PRIORITY = 0;

int SearchProcess(int, char*, DWORD, int, DWORD, DWORD, int);
int privilege(LPTSTR pszPrivilege, BOOL bEnable);
// ermittle Parent-Prozess-ID zu Prozess-ID
DWORD GetParentProcessID(DWORD);
// I/O- und Speicherpriorität ermitteln
int queryPriority(HANDLE, DWORD*, DWORD*);
// I/O- und Speicherpriorität setzen
int setPriority(HANDLE, DWORD, DWORD);

int main(int argc, char* argv[])
{ int rc = 0, iSet = 0, iMode = 0, iInstance = 1;
  DWORD_PTR dwSysMask, dwCPUMask = 0;
  DWORD dwPrioToSet = NORMAL_PRIORITY_CLASS;
  DWORD ProcID = 0;
  char ProcParam[1024] = "";

  if ((argc > 1) && ((stricmp(argv[1], "-?") == 0) || (stricmp(argv[1], "/?") == 0)))
  { printf("Priority.exe                               (c) Markus Scholtes 2002, 2010, 2017\n\n");
    printf("Usage: Priority [<parameter>] [<PID|program>]\n\n");
    printf("Shows (when called without parameters) or changes the CPU, memory and I/O \n");
    printf("priority and CPU affinity of a running process (memory priority can maximally\n");
    printf("be set  to normal, I/O priority to high at most).\n");
    printf("It is enough to supply a partly process name. Only the first found process is\n");
    printf("processed (see parameter /INSTANCE). If no process ID and no program name is\n");
    printf("supplied, the calling process is processed.\n\n");
		printf("Parameters:\n");
    printf("/INSTANCE:n - n. found process with name part is processed (default: 1.).\n");
    printf("/INSTANCE:ALL - all found processes with name part are processed.\n");
    printf("/LOW /BELOWNORMAL /NORMAL /ABOVENORMAL /HIGH /REALTIME\n");
    printf("                                  - process gets respective priority.\n");
    printf("/ONLYCPU - only CPU priority is set.\n");
    printf("/CPUMASK:n - CPU affinity. Sum of 1=CPU0, 2=CPU1, 4=CPU2, 8=CPU3,... .\n");
    exit(0); }

  // Parameter auswerten
  for (int i = 1; i < argc; i++)
  { if ((argv[i][0] == '/') || (argv[i][0] == '-'))
    { switch (toupper(argv[i][1]))
      { case 'R':
      		if (strncmpi(argv[i]+1, "REALTIME", 8) == 0)
				  { dwPrioToSet = REALTIME_PRIORITY_CLASS;
				    iSet |= 1; }
				  else
				    rc = 1;
				  break;

				case 'H':
					if (strncmpi(argv[i]+1, "HIGH", 4) == 0)
				  { dwPrioToSet = HIGH_PRIORITY_CLASS;
				    iSet |= 1; }
			    else
				    rc = 1;
				  break;

				case 'A':
					if (strncmpi(argv[i]+1, "ABOVENORMAL",11) == 0)
				  { dwPrioToSet = ABOVE_NORMAL_PRIORITY_CLASS;
				    iSet |= 1; }
				  else
				    rc = 1;
				  break;

				case 'N':
					if (strncmpi(argv[i]+1, "NORMAL", 6) == 0)
				  { dwPrioToSet = NORMAL_PRIORITY_CLASS;
				    iSet |= 1; }
				  else
				    rc = 1;
				  break;

				case 'B':
					if (strncmpi(argv[i]+1, "BELOWNORMAL", 11) == 0)
				  { dwPrioToSet = BELOW_NORMAL_PRIORITY_CLASS;
				    iSet |= 1; }
				  else
				    rc = 1;
				  break;

				case 'L':
					if (strncmpi(argv[i]+1, "LOW", 3) == 0)
				  { dwPrioToSet = IDLE_PRIORITY_CLASS;
				    iSet |= 1; }
				  else
				    rc = 1;
				  break;

				case 'O':
					if (strncmpi(argv[i]+1, "ONLYCPU", 7) == 0)
				    iSet |= 4;
			   else
				    rc = 1;
				  break;

				case 'C':
					if (strncmpi(argv[i]+1, "CPUMASK:", 8) == 0)
				  { HANDLE procHandle = GetCurrentProcess();
		        if (!GetProcessAffinityMask(procHandle, &dwCPUMask, &dwSysMask))
				    { fprintf(stderr, "Cannot retrieve CPU count.\n");
				      rc = 2; }
				    else
				    { dwCPUMask = atoi(argv[i] + 9);
				      if (((dwCPUMask | dwSysMask)!=dwSysMask) || (dwCPUMask<1))
				      { fprintf(stderr, "Invalid CPU mask.\n");
				        rc = 2; }
				    }
				    iSet |= 2;
				  }
				  else
				    rc = 1;
				  break;

				case 'I':
					if (strncmpi(argv[i]+1, "INSTANCE:", 9) == 0)
				  { if (strncmpi(argv[i]+10, "ALL", 3) == 0)
				  		iInstance = -1;
				  	else
				  	{
				  		iInstance = atoi(argv[i] + 10);
				    	if (iInstance < 1)
				    	{ fprintf(stderr, "Invalid instance number.\n");
				      	rc = 2;
				    	}
				    }
				  }
				  else
				    rc = 1;
				  break;

				default:
					rc = 1;
				 break;
	    }
    }
    else
    { while (i < argc)
      { if (ProcParam[0] != 0) strcat(ProcParam," ");
        strcat(ProcParam, argv[i]);
        i++; }
    }
  }

  // PID oder Prozessname übergeben?
  for (unsigned int j = 0; (j < strlen(ProcParam)) && (iMode == 0); j++)
  { if ((ProcParam[j] < '0') || (ProcParam[j] > '9')) iMode=1;
  }

  // wenn iMode == 0, dann ProcID
  if (iMode == 0) ProcID=atol(ProcParam);

  if (ProcParam[0] == 0)
  { // ProzessID des aufrufenden Prozesses ermitteln
  	ProcID = GetParentProcessID(GetCurrentProcessId());
  	iMode = 0;
  	if (!rc) printf("Processing calling process...\n");
  }

	if (((iMode == 0) && (iInstance != 1)) || ((iSet & 5) == 4))
  { fprintf(stderr, "Inconsitent parameters.\n");
    return 1; }

  if ((rc) || ((iMode == 0) && (ProcID < 20)))
  { if (rc != 2) fprintf(stderr, "Wrong parameters.\n");
    return 1; }

  if (privilege(SE_DEBUG_NAME, TRUE))
  { fprintf(stderr, "Debug privilege denied.\n");
    exit(1); }

  if (privilege(SE_INC_BASE_PRIORITY_NAME, TRUE))
  { fprintf(stderr, "Privilege to increase base priority denied.\n");
    exit(1); }

  rc = SearchProcess(iMode, ProcParam, ProcID, iSet, dwPrioToSet, dwCPUMask, iInstance);

  privilege(SE_INC_BASE_PRIORITY_NAME, FALSE);
  privilege(SE_DEBUG_NAME, FALSE);
  return rc;
}

// SearchProcess - Suche Prozess mit PID "ProcID" oder Prozessnamenteil "ProzName" (wenn iMode == 1)
int SearchProcess(int iMode, char *ProzName, DWORD ProcID, int iSet, DWORD dwPrior, DWORD dwCPU, int iInstance)
{ DWORD aProcesses[1024], cbNeeded, cProcesses, dwValue;
  char szProcessName[MAX_PATH] = "<unknown>";
  unsigned int i;
  HANDLE hProcess;
  bool bFound = false;
  int iFound = 0;
  int rc = 0;

  // Liste aller laufenden PIDs ermitteln
  if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
  { fprintf(stderr, "Cannot retrieve process list.\n");
    return 1;
  }

  // Anzahl PIDs
  cProcesses = cbNeeded / sizeof(DWORD);

  // Name und PID ausgeben
  for (i = 0; (i < cProcesses) && (!bFound); i++)
  { if (iMode == 1)
    { // Prozess Handle zur PID ermitteln
      hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i]);
      if (hProcess)
      { HMODULE hMod;
        DWORD cbNeeded;

        // Prozessname ermitteln
        if(EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
          GetModuleBaseName(hProcess, hMod, szProcessName, sizeof(szProcessName));
        if (strncmpi(ProzName, szProcessName, strlen(ProzName)) == 0)
        {
         	iFound++;
         	if ((iFound == iInstance) || (iInstance == -1))
         		bFound = true;
        }
        else
          CloseHandle(hProcess);
      }
    }
    else
      if (ProcID == aProcesses[i])
      { bFound = true;
      	iFound = 1;
        // Prozess Handle zur PID ermitteln
        hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i]);
        if (hProcess)
        { HMODULE hMod;
          DWORD cbNeeded;

          // Prozessname ermitteln
          if(EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
            GetModuleBaseName(hProcess, hMod, szProcessName, sizeof(szProcessName));
				}
      }

    if (bFound)
    { if ((iSet & 2) && (dwCPU))
      { if (!SetProcessAffinityMask(hProcess, dwCPU))
        { fprintf(stderr, "Error %d trying to set CPU affinity.\n", GetLastError());
          rc = 1; }
        else
          printf("CPU affinity of %s [%u] set to %d.\n", szProcessName, aProcesses[i], dwCPU);
      }

      if (iSet & 1)
      { if (!SetPriorityClass(hProcess, dwPrior))
        { fprintf(stderr, "Error %d trying to set priority.\n", GetLastError());
          rc = 1; }
        else
        { DWORD dwIOPrio, dwMemPrio;

					printf("Priority of %s [%u] set to CPU ", szProcessName, aProcesses[i]);
          switch (dwPrior)
          { case REALTIME_PRIORITY_CLASS: printf("real time");
          			dwMemPrio = NORMAL_MEMORY_PRIORITY;
          			dwIOPrio = HIGH_IO_PRIORITY;
   			      break;
            case HIGH_PRIORITY_CLASS: printf("high");
          			dwMemPrio = NORMAL_MEMORY_PRIORITY;
          			dwIOPrio = HIGH_IO_PRIORITY;
   			      break;
            case ABOVE_NORMAL_PRIORITY_CLASS: printf("above normal");
          			dwMemPrio = NORMAL_MEMORY_PRIORITY;
          			dwIOPrio = NORMAL_IO_PRIORITY;
   			      break;
            case NORMAL_PRIORITY_CLASS: printf("normal");
          			dwMemPrio = NORMAL_MEMORY_PRIORITY;
          			dwIOPrio = NORMAL_IO_PRIORITY;
   			      break;
            case BELOW_NORMAL_PRIORITY_CLASS: printf("below normal");
          			dwMemPrio = LOW_MEMORY_PRIORITY;
          			dwIOPrio = LOW_IO_PRIORITY;
   			      break;
            case IDLE_PRIORITY_CLASS: printf("low");
          			dwMemPrio = VERYLOW_MEMORY_PRIORITY;
          			dwIOPrio = VERYLOW_IO_PRIORITY;
   			      break;
          }

          if ((iSet & 4) == 0)
          {
	          // Setzen der IO- und Speicherpriorität
	          if (setPriority(hProcess, dwMemPrio, dwIOPrio))
	          { // Fehler beim Setzen der I/O- oder Speicherpriorität
	          	printf(".\n");
	          	rc = 1;
	          }
	          else
	          { // Speicherpriorität
	          	printf(", memory ");
	          	switch (dwMemPrio)
	          	{
								case CRITICAL_MEMORY_PRIORITY: printf("real time (%d)", dwMemPrio);
	     			      break;
								case HIGH_MEMORY_PRIORITY: printf("high (%d)", dwMemPrio);
	     			      break;
								case NORMAL_MEMORY_PRIORITY: printf("normal (%d)", dwMemPrio);
	     			      break;
								case BELOWNORMAL_MEMORY_PRIORITY: printf("below normal (%d)", dwMemPrio);
	     			      break;
								case LOW_MEMORY_PRIORITY: printf("low (%d)", dwMemPrio);
	     			      break;
								case BELOWLOW_MEMORY_PRIORITY: printf("below low (%d)", dwMemPrio);
	     			      break;
								case VERYLOW_MEMORY_PRIORITY: printf("very low (%d)", dwMemPrio);
	     			      break;
								case BELOWVERYLOW_MEMORY_PRIORITY: printf("below very low (%d)", dwMemPrio);
	     			      break;
							}

	          	// I/O-Priorität
	          	printf(", I/O ");
	          	switch (dwIOPrio)
	          	{
								case CRITICAL_IO_PRIORITY: printf("real time (%d)", dwIOPrio);
	     			      break;
								case HIGH_IO_PRIORITY: printf("high (%d)", dwIOPrio);
	     			      break;
								case NORMAL_IO_PRIORITY: printf("normal (%d)", dwIOPrio);
	     			      break;
								case LOW_IO_PRIORITY: printf("low (%d)", dwIOPrio);
	     			      break;
								case VERYLOW_IO_PRIORITY: printf("very low (%d)", dwIOPrio);
	     			      break;
							}
	          printf(".\n");
						}
					}
					else
	          printf(".\n");
        }
      }

      if (iSet == 0)
      { printf("%s [%u]\n", szProcessName, aProcesses[i]);

        dwValue = GetPriorityClass(hProcess);
        if (dwValue == 0)
        { fprintf(stderr, "cannot retrieve priority, Error %d.\n", GetLastError());
          rc = 1; }
        else
        { printf("Priorities: CPU ");
          switch (dwValue)
          { case REALTIME_PRIORITY_CLASS: printf("real time");
   			      break;
            case HIGH_PRIORITY_CLASS: printf("high");
   			      break;
            case ABOVE_NORMAL_PRIORITY_CLASS: printf("above normal");
   			      break;
            case NORMAL_PRIORITY_CLASS: printf("normal");
   			      break;
            case BELOW_NORMAL_PRIORITY_CLASS: printf("below normal");
   			      break;
            case IDLE_PRIORITY_CLASS: printf("low");
   			      break;
          }

          DWORD dwIOPrio, dwMemPrio;
          // Ermitteln der IO- und Speicherpriorität
          if (queryPriority(hProcess, &dwMemPrio, &dwIOPrio))
          { // Fehler beim Ermitteln der IO- oder Speicherpriorität
          	printf("\n");
          	rc = 1;
          }
          else
          { // Speicherpriorität
          	printf(", memory ");
          	switch (dwMemPrio)
          	{
							case CRITICAL_MEMORY_PRIORITY: printf("real time (%d)", dwMemPrio);
     			      break;
							case HIGH_MEMORY_PRIORITY: printf("high (%d)", dwMemPrio);
     			      break;
							case NORMAL_MEMORY_PRIORITY: printf("normal (%d)", dwMemPrio);
     			      break;
							case BELOWNORMAL_MEMORY_PRIORITY: printf("below normal (%d)", dwMemPrio);
     			      break;
							case LOW_MEMORY_PRIORITY: printf("low (%d)", dwMemPrio);
     			      break;
							case BELOWLOW_MEMORY_PRIORITY: printf("below low (%d)", dwMemPrio);
     			      break;
							case VERYLOW_MEMORY_PRIORITY: printf("very low (%d)", dwMemPrio);
     			      break;
							case BELOWVERYLOW_MEMORY_PRIORITY: printf("below very low (%d)", dwMemPrio);
     			      break;
						}

          	// I/O-Priorität
          	printf(", I/O ");
          	switch (dwIOPrio)
          	{
							case CRITICAL_IO_PRIORITY: printf("realtime (%d)", dwIOPrio);
     			      break;
							case HIGH_IO_PRIORITY: printf("high (%d)", dwIOPrio);
     			      break;
							case NORMAL_IO_PRIORITY: printf("normal (%d)", dwIOPrio);
     			      break;
							case LOW_IO_PRIORITY: printf("low (%d)", dwIOPrio);
     			      break;
							case VERYLOW_IO_PRIORITY: printf("very low (%d)", dwIOPrio);
     			      break;
						}
	          printf("\n");
					}
        }

        DWORD_PTR dwCPUMask, dwSysMask;
        if (!GetProcessAffinityMask(hProcess, &dwCPUMask, &dwSysMask))
        { fprintf(stderr, "Cannot retrieve CPU affinity, error %d.\n", GetLastError());
          rc = 1; }
        else
          printf("CPU affinity: %d\n", dwCPUMask);
      }

      CloseHandle(hProcess);
    }
    if (iInstance == -1) bFound = false;
  }

	if (iInstance == -1)
    printf("Found %d process(es) with name part \"%s\".\n", iFound, ProzName);
	else
  {	if (iFound != iInstance)
  	{ if (iMode == 1)
  		{
      	if (iInstance > 1) fprintf(stderr, "%d. instance of ", iInstance);
	      fprintf(stderr, "process with name part \"%s\" not found.\n", ProzName);
  	  }
    	else
      	fprintf(stderr, "Process with ID %d not found.\n", ProcID);
	    return 1;
  	}
  }

  return rc;
}

int privilege(LPTSTR pszPrivilege, BOOL bEnable)
{ HANDLE hToken;
  TOKEN_PRIVILEGES tp;

  // ermittle den Prozess Token
  if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken))
    return 1;

  // ermittle die luid
  if (!LookupPrivilegeValue(NULL, pszPrivilege, &tp.Privileges[0].Luid))
    return 1;

  tp.PrivilegeCount=1;

  if (bEnable)
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  else
    tp.Privileges[0].Attributes = 0;

  // Privileg für Prozess ermöglichen/sperren
  if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0))
    return 1;

  if (!CloseHandle(hToken)) return 1;

  return 0;
}

// ab hier Prozessmanagement zum Ermitteln der Parentprozess-ID (mit NtQueryInformationProcess)
// und zum Setzen der IO- und Speicherpriorität (mit NtSetInformationProcess)

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING;

typedef struct _RTL_USER_PROCESS_PARAMETERS {
    BYTE Reserved1[16];
    PVOID Reserved2[10];
    UNICODE_STRING ImagePathName;
    UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

typedef struct _PEB_LDR_DATA {
    BYTE Reserved1[8];
    PVOID Reserved2[3];
    LIST_ENTRY InMemoryOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;

typedef void (NTAPI *PPS_POST_PROCESS_INIT_ROUTINE) (VOID);

#ifdef _WIN64
typedef struct _PEB {
    BYTE Reserved1[2];
    BYTE BeingDebugged;
    BYTE Reserved2[21];
    PPEB_LDR_DATA LoaderData;
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
    BYTE Reserved3[520];
    PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
    BYTE Reserved4[136];
    ULONG SessionId;
} PEB, *PPEB;
#else
typedef struct _PEB {
    BYTE Reserved1[2];
    BYTE BeingDebugged;
    BYTE Reserved2[1];
    PVOID Reserved3[2];
    PPEB_LDR_DATA Ldr;
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
    BYTE Reserved4[104];
    PVOID Reserved5[52];
    PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
    BYTE Reserved6[128];
    PVOID Reserved7[1];
    ULONG SessionId;
} PEB, *PPEB;
#endif

typedef struct _PROCESS_BASIC_INFORMATION {
    PVOID Reserved1;
    PPEB PebBaseAddress;
  	PVOID AffinityMask; // in Wintern.l:
  	PVOID BasePriority; //    PVOID Reserved2[2];
    ULONG_PTR UniqueProcessId;
    PVOID InheritedFromUniqueProcessId; // in Wintern.l: PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;

typedef enum _PROCESSINFOCLASS {
    ProcessBasicInformation = 0x00,
    ProcessWow64Information = 0x1A,
    ProcessIoPriority = 0x21,
    ProcessPagePriority = 0x27
} PROCESSINFOCLASS;

typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)(
  IN HANDLE ProcessHandle,
  IN PROCESSINFOCLASS ProcessInformationClass,
  OUT PVOID ProcessInformation,
  IN ULONG ProcessInformationLength,
  OUT PULONG ReturnLength OPTIONAL
);

typedef NTSTATUS (NTAPI *_NtSetInformationProcess)(
	IN HANDLE process,
	ULONG infoClass,
	void* data,
	ULONG dataSize
);

// ermittle Parent-Prozess-ID zu Prozess-ID
DWORD GetParentProcessID(DWORD dwId)
{ LONG status;
  DWORD dwParentPID = (DWORD) -1;
  HANDLE hProcess;
  PROCESS_BASIC_INFORMATION pbi;

  // Funktionsadresse von "NtQueryInformationProcess()" dynamisch aus NTDLL.DLL laden
  _NtQueryInformationProcess fncNtQueryInformationProcess = (_NtQueryInformationProcess)GetProcAddress(GetModuleHandle("ntdll"), "NtQueryInformationProcess");

  // hat geklappt?
  if (!fncNtQueryInformationProcess)
  { // nein -> Fehler
    fprintf(stderr, "Loading of DLL NTDLL.DLL failed.\n");
    return (DWORD)-1;
  }

  // Hole Prozess-Handle
  hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwId);
  if (!hProcess)
  { // Fehler
  	fprintf(stderr, "Error retrieving the process handle.\n");
    return (DWORD)-1;
  }

  // Information über Prozess ermitteln
  status = fncNtQueryInformationProcess(hProcess, ProcessBasicInformation, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL);

  // Bei Erfolg Prozess-ID des parents lesen
  if (!status) dwParentPID = (DWORD)pbi.InheritedFromUniqueProcessId;
//  if (!status) dwParentPID = (DWORD)pbi.Reserved3;
  else
  	fprintf(stderr, "Error retrieving the ID of the parent process.\n");

  // Handle freigeben
  CloseHandle(hProcess);

  // Prozess-ID zurückgeben
  return dwParentPID;
}

// I/O- und Speicherpriorität ermitteln
int queryPriority(HANDLE hProcess, DWORD* dwMemPrio, DWORD* dwIOPrio)
{ NTSTATUS result;
	ULONG len;

  // Funktionsadresse von "NtQueryInformationProcess()" dynamisch aus NTDLL.DLL laden
  _NtQueryInformationProcess fncNtQueryInformationProcess = (_NtQueryInformationProcess)GetProcAddress(GetModuleHandle("ntdll"), "NtQueryInformationProcess");

  // hat geklappt?
  if (!fncNtQueryInformationProcess)
  { // nein -> Fehler
    fprintf(stderr, "Loading of DLL NTDLL.DLL failed.\n");
    return -1;
  }
	// Speicherpriorität ermitteln
	result = fncNtQueryInformationProcess(hProcess, ProcessPagePriority, dwMemPrio, sizeof(DWORD), &len);
	if (result != 0 || len != sizeof(DWORD))
	{ fprintf(stderr, "\nError %x retrieving the memory priority.\n", result);
		return -1;
	}

	// I/O-Priorität ermitteln
	result = fncNtQueryInformationProcess(hProcess, ProcessIoPriority, dwIOPrio, sizeof(DWORD), &len);
	if (result != 0 || len != sizeof(DWORD))
	{ fprintf(stderr, "\nError %x retrieving the I/O priority.\n", result);
		return -1;
	}

	return 0;
}

// I/O- und Speicherpriorität setzen
int setPriority(HANDLE hProcess, DWORD dwMemPrio, DWORD dwIOPrio)
{ NTSTATUS result;

  // Funktionsadresse von "NtQueryInformationProcess()" dynamisch aus NTDLL.DLL laden
  _NtSetInformationProcess fncNtSetInformationProcess = (_NtSetInformationProcess)GetProcAddress(GetModuleHandle("ntdll"), "NtSetInformationProcess");

  // hat geklappt?
  if (!fncNtSetInformationProcess)
  { // nein -> Fehler
    fprintf(stderr, "Loading of DLL NTDLL.DLL failed.\n");
    return -1;
  }
	// Speicherpriorität ermitteln
	result = fncNtSetInformationProcess(hProcess, ProcessPagePriority, &dwMemPrio, sizeof(DWORD));
	if (result != 0)
	{ fprintf(stderr, "\nError %x setting the memory priority.\n", result);
		return -1;
	}

	// I/O-Priorität ermitteln
	result = fncNtSetInformationProcess(hProcess, ProcessIoPriority, &dwIOPrio, sizeof(DWORD));
	if (result != 0)
	{ fprintf(stderr, "\nError %x setting the I/O priority.\n", result);
		return -1;
	}

	return 0;
}


text:
namespace OptionNames
{
const DAVA::String Compression = "-compression";
const DAVA::String BaseDir = "-basedir";
const DAVA::String MetaDbFile = "-metadb";
const DAVA::String DummyFileData = "-dummyFileData";
}

ArchivePackTool::ArchivePackTool()
    : CommandLineTool("pack")
{
    using namespace DAVA;

    options.AddOption(OptionNames::Compression, VariantType(String("lz4hc")), "default compression method, lz4hc - default");
    options.AddOption(OptionNames::BaseDir, VariantType(String("")), "source base directory");
    options.AddOption(OptionNames::MetaDbFile, VariantType(String("")), "sqlite db with metadata");
    options.AddOption(OptionNames::DummyFileData, VariantType(false), "write dummy single-byte files instead of actual file data, useful if you are interested in pack footer only");
    options.AddArgument("packfile");
}

bool ArchivePackTool::ConvertOptionsToParamsInternal()
{
    using namespace DAVA;
    compressionStr = options.GetOption(OptionNames::Compression).AsString();

    int type;
    if (!GlobalEnumMap<Compressor::Type>::Instance()->ToValue(compressionStr.c_str(), type))
    {
        Logger::Error("Invalid compression type: '%s'", compressionStr.c_str());
        return false;
    }
    compressionType = static_cast<Compressor::Type>(type);

    dummyFileData = options.GetOption(OptionNames::DummyFileData).AsBool();

    baseDir = options.GetOption(OptionNames::BaseDir).AsString();
    if (baseDir.empty())
    {
        Logger::Error("%s - param is not specified", OptionNames::BaseDir.c_str());
        return false;
    }
    metaDbPath = options.GetOption(OptionNames::MetaDbFile).AsString();
    if (metaDbPath.empty())
    {
        Logger::Error("%s - param is not specified", OptionNames::MetaDbFile.c_str());
        return false;
    }

    packFileName = options.GetArgument("packfile");
    if (packFileName.empty())
    {
        Logger::Error("packfile param is not specified");
        return false;
    }

    return true;
}

int ArchivePackTool::ProcessInternal()
{
    using namespace DAVA;

    ResourceArchiver::Params params;
    params.compressionType = compressionType;
    params.archivePath = packFileName;
    params.baseDirPath = (baseDir.empty() ? FileSystem::Instance()->GetCurrentWorkingDirectory() : baseDir);
    params.metaDbPath = metaDbPath;
    params.dummyFileData = dummyFileData;

    if (!CreateArchive(params))
    {
        return ERROR_CANT_WRITE_FILE;
    }

    return OK;
}


text:
package com.prnk.friendscore;

import android.app.Dialog;
import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Toast;

public class EditActivity extends ListActivity {
    private GameObject currentGame;		//current game being edited or created
    private TeamListAdapter adapter;	//custom list adapter
    private DataBaseWrapper dbwrapper;	//database wrapper

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.edit_game);

		dbwrapper = new DataBaseWrapper(this);

		Bundle b = getIntent().getExtras();
		if(b != null) {
			int gameId = b.getInt("EDIT_GAME_ID");
			currentGame = dbwrapper.getGameObject(gameId);

			//populate fields
			EditText titleEdit = (EditText) findViewById(R.id.editTitle);
			titleEdit.setText(currentGame.Title());
		} else {
			currentGame = new GameObject();
		}

		getActionBar().setTitle(
				(currentGame.GetId() == 0)
				? R.string.createScoreboard
				: R.string.editScoreboard);
		//set up the list view and the buttons
		SetupListView();
		SetupRemoveButton();
	}

	//Displays the dialog for entering or editing a team name
	private void DisplayEditTeamDialog(final String currentName) {
		final Dialog dialog = new Dialog(this);
		dialog.setContentView(R.layout.edit_team_dialog);
		dialog.setTitle(R.string.newTeamDialogMessage);

		EditText edit = (EditText) dialog.findViewById(R.id.editTeamName);
		edit.setText(currentName);

		Button doneButton = (Button) dialog.findViewById(R.id.dialogDoneButton);
		doneButton.setOnClickListener(new Button.OnClickListener() {
		    public void onClick(View v) {
		    		EditText editTeamName = (EditText)dialog.findViewById(R.id.editTeamName);
		            String newName = editTeamName.getText().toString();
		            if(!newName.equals("")) {
		            	if(!currentGame.ContainsTeamName(newName)) {
		            		if(currentName.equals("")) {
		            			currentGame.teams.add(new TeamObject(newName));
		            		} else {
		            			currentGame.GetTeamByName(currentName).SetName(newName);
		            		}
				            dialog.dismiss();
		            		adapter.notifyDataSetChanged();
		            	}
		            }
		    }
		});

		Button cancelButton = (Button) dialog.findViewById(R.id.dialogCancelButton);
		cancelButton.setOnClickListener(new Button.OnClickListener() {
		    public void onClick(View v) {
		            dialog.dismiss();
		    }
		});
		dialog.show();
	}

	public void onAddTeamClick(View v) {
		DisplayEditTeamDialog("");
	}

	public void onCancelEditGameButton(View v) {
		//don't write to the database
		finish();
	}

	public void onDoneEditGameButton(View v) {
		if(!currentGame.teams.isEmpty()) {
			//write the game into the database
			EditText editTitle = (EditText)this.findViewById(R.id.editTitle);
			currentGame.SetTitle(editTitle.getText().toString());
			if(currentGame.GetId() == 0) {
				//not in the database
				dbwrapper.createGame(currentGame);
			}

			//return to the calling view
			finish();
		}
	}

	private void SetupRemoveButton() {
		Button remove = (Button) findViewById(R.id.removeTeam);
		remove.setOnClickListener(new Button.OnClickListener() {
		   @Override
		   public void onClick(View v) {
			   currentGame.RemoveSelectedTeams();
			   adapter.notifyDataSetChanged();
		   }
		});
	}

	private void SetupListView() {
		getListView().setItemsCanFocus(false);
		getListView().setTextFilterEnabled(true);
		adapter = new TeamListAdapter(this, R.layout.checkboxed_listview_item, currentGame);
		ListView teamListView = getListView();
		teamListView.setAdapter(adapter);
	}

	private class TeamListAdapter extends ArrayAdapter<TeamObject> {
		private GameObject game;
		private Context context;

		public TeamListAdapter(Context context, int teamNameResourceId, GameObject game) {
			super(context, teamNameResourceId, game.teams);
			this.context = context;
			this.game = game;
		}

		@Override
		public int getCount() {
			if(game.teams.isEmpty()) {
				return 1;
			}
			return game.teams.size();
		}

		@Override
		public boolean isEmpty () {
			return game.teams.isEmpty();
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			if(isEmpty()) {
				LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			    convertView = inflater.inflate(R.layout.empty_team_list_item, parent, false);
			    return convertView;
			}

			CheckBox box;
			if(convertView == null) {
				LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			    convertView = inflater.inflate(R.layout.checkboxed_listview_item, parent, false);
			    box = (CheckBox) convertView.findViewById(R.id.teamCheckBox);
			    box.setOnCheckedChangeListener(new OnCheckedChangeListener() {
					@Override
					public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
						TeamObject team = game.GetTeamByName(buttonView.getText().toString());
						team.SetSelected(isChecked);
					}
				});
			    box.setText(game.Team(position).Name());
			    convertView.setTag(box);

			    ImageButton edit = (ImageButton) convertView.findViewById(R.id.editTeamName);
			    edit.setOnClickListener(new Button.OnClickListener() {
					@Override
					public void onClick(View v) {
						CheckBox box = (CheckBox) ((View)v.getParent()).findViewById(R.id.teamCheckBox);
						DisplayEditTeamDialog(box.getText().toString());
					}
			    });
			} else {
				box = (CheckBox) convertView.getTag();
				if(box == null) {
					LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				    convertView = inflater.inflate(R.layout.checkboxed_listview_item, parent, false);
				    box = (CheckBox) convertView.findViewById(R.id.teamCheckBox);
				    box.setOnCheckedChangeListener(new OnCheckedChangeListener() {
						@Override
						public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
							TeamObject team = game.GetTeamByName(buttonView.getText().toString());
							team.SetSelected(isChecked);
						}
					});
				    box.setText(game.Team(position).Name());
				    convertView.setTag(box);

				    ImageButton edit = (ImageButton) convertView.findViewById(R.id.editTeamName);
				    edit.setOnClickListener(new Button.OnClickListener() {
						@Override
						public void onClick(View v) {
							CheckBox box = (CheckBox) ((View)v.getParent()).findViewById(R.id.teamCheckBox);
							DisplayEditTeamDialog(box.getText().toString());
						}
				    });
				}
			}

			TeamObject team = this.game.Team(position);
			if(team != null) {
				box.setText(team.Name());
				box.setChecked(team.Selected());
			}
		    return convertView;
		}
	}
}