text:
package org.drools.modelcompiler.builder.generator.expression;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;

import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.expr.BinaryExpr;
import com.github.javaparser.ast.expr.ClassExpr;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.FieldAccessExpr;
import com.github.javaparser.ast.expr.LambdaExpr;
import com.github.javaparser.ast.expr.LiteralExpr;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.expr.NameExpr;
import com.github.javaparser.ast.expr.StringLiteralExpr;
import com.github.javaparser.ast.stmt.ExpressionStmt;
import org.drools.modelcompiler.builder.generator.RuleContext;
import org.drools.modelcompiler.builder.generator.TypedExpression;
import org.drools.modelcompiler.builder.generator.drlxparse.DrlxParseSuccess;
import org.drools.modelcompiler.builder.generator.drlxparse.MultipleDrlxParseSuccess;
import org.drools.modelcompiler.builder.generator.drlxparse.SingleDrlxParseSuccess;

import static com.github.javaparser.StaticJavaParser.parseClassOrInterfaceType;
import static com.github.javaparser.StaticJavaParser.parseType;
import static java.util.Optional.of;
import static org.drools.modelcompiler.builder.generator.DrlxParseUtil.THIS_PLACEHOLDER;
import static org.drools.modelcompiler.builder.generator.DslMethodNames.ALPHA_INDEXED_BY_CALL;
import static org.drools.modelcompiler.builder.generator.DslMethodNames.BETA_INDEXED_BY_CALL;

public class PatternExpressionBuilder extends AbstractExpressionBuilder {

    public static final String EXPR_CALL = "expr";
    public static final String REACT_ON_CALL = "D.reactOn";
    public static final String BIND_CALL = "bind";
    public static final String OR_CALL = "or";
    public static final String AND_CALL = "and";
    public static final String END_OR_CALL = "endOr";
    public static final String END_AND_CALL = "endAnd";

    public PatternExpressionBuilder(RuleContext context) {
        super(context);
    }

    @Override
    public void processExpression(SingleDrlxParseSuccess drlxParseResult) {
        if (drlxParseResult.hasUnificationVariable()) {
            Expression dslExpr = buildUnificationExpression(drlxParseResult);
            context.addExpression(dslExpr);
        } else if (drlxParseResult.isValidExpression()) {
            Expression dslExpr = buildExpressionWithIndexing(drlxParseResult);
            context.addExpression(dslExpr);
        }

        if (drlxParseResult.getExprBinding() != null) {
            Expression dslExpr = buildBinding(drlxParseResult);
            context.addExpression(dslExpr);
        }
    }

    @Override
    public MethodCallExpr buildExpressionWithIndexing(DrlxParseSuccess drlxParseResult) {
        if (drlxParseResult instanceof MultipleDrlxParseSuccess) {
            MultipleDrlxParseSuccess multi = ( MultipleDrlxParseSuccess ) drlxParseResult;
            MethodCallExpr exprDSL = new MethodCallExpr(null, multi.getOperator() == BinaryExpr.Operator.OR ? OR_CALL : AND_CALL);
            for (DrlxParseSuccess child : multi.getResults()) {
                MethodCallExpr childExpr = buildExpressionWithIndexing(child);
                childExpr.setScope( exprDSL );
                exprDSL = childExpr;
            }
            return new MethodCallExpr(exprDSL, multi.getOperator() == BinaryExpr.Operator.OR ? END_OR_CALL : END_AND_CALL);
        }
        return buildSingleExpressionWithIndexing((SingleDrlxParseSuccess ) drlxParseResult);
    }

    private MethodCallExpr buildSingleExpressionWithIndexing(SingleDrlxParseSuccess drlxParseResult) {
        String exprId = drlxParseResult.getExprId(context.getPackageModel().getExprIdGenerator());
        MethodCallExpr exprDSL = new MethodCallExpr(null, EXPR_CALL);
        if (exprId != null && !"".equals(exprId)) {
            exprDSL.addArgument(new StringLiteralExpr(exprId));
        }

        exprDSL = buildExpression(drlxParseResult, exprDSL);
        MethodCallExpr finalExprDSL = exprDSL;
        buildIndexedBy(drlxParseResult).ifPresent(finalExprDSL::addArgument);
        buildReactOn(drlxParseResult).ifPresent(finalExprDSL::addArgument);
        return exprDSL;
    }

    private MethodCallExpr buildExpression(SingleDrlxParseSuccess drlxParseResult, MethodCallExpr exprDSL) {
        final List<String> usedDeclarationsWithUnification = new ArrayList<>();
        usedDeclarationsWithUnification.addAll(drlxParseResult.getUsedDeclarations());

        if (drlxParseResult.isTemporal() && drlxParseResult.getLeft() != null && !drlxParseResult.getLeft().getExpression().isNameExpr()) {
            exprDSL.addArgument(generateLambdaForTemporalConstraint(drlxParseResult.getLeft(), drlxParseResult.getPatternType()));
        }

        usedDeclarationsWithUnification.stream()
                .filter( s -> !(drlxParseResult.isSkipThisAsParam() && s.equals( drlxParseResult.getPatternBinding() ) ) )
                .map(context::getVarExpr)
                .forEach(exprDSL::addArgument);

        if (drlxParseResult.getRightLiteral() != null) {
            exprDSL.addArgument( "" + drlxParseResult.getRightLiteral() );
        } else {
            if (drlxParseResult.isTemporal() && drlxParseResult.getRight() != null && !drlxParseResult.getRight().getExpression().isNameExpr()) {
                exprDSL.addArgument(generateLambdaForTemporalConstraint(drlxParseResult.getRight(), drlxParseResult.getPatternType()));
            }
        }

        exprDSL.addArgument(buildConstraintExpression(drlxParseResult, drlxParseResult.getExpr()));
        return exprDSL;
    }

    private Optional<MethodCallExpr> buildReactOn(SingleDrlxParseSuccess drlxParseResult) {
        if (shouldBuildReactOn(drlxParseResult)) {
            MethodCallExpr reactOnDSL = new MethodCallExpr(null, REACT_ON_CALL);
            drlxParseResult.getReactOnProperties().stream()
                    .map(StringLiteralExpr::new)
                    .forEach(reactOnDSL::addArgument);
            return of(reactOnDSL);
        }
        return Optional.empty();
    }

    @Override
    public MethodCallExpr buildBinding(SingleDrlxParseSuccess drlxParseResult) {
        MethodCallExpr bindDSL = new MethodCallExpr(null, BIND_CALL);
        if (drlxParseResult.hasUnificationVariable()) {
            bindDSL.addArgument(context.getVarExpr(drlxParseResult.getUnificationVariable()));
        } else {
            bindDSL.addArgument(context.getVarExpr(drlxParseResult.getExprBinding()));
        }
        final Expression constraintExpression = getConstraintExpression(drlxParseResult);
        drlxParseResult.getUsedDeclarationsOnLeft().forEach(d -> bindDSL.addArgument(context.getVar(d)));
        bindDSL.addArgument(constraintExpression);
        final Optional<MethodCallExpr> methodCallExpr = buildReactOn(drlxParseResult);
        methodCallExpr.ifPresent(bindDSL::addArgument);
        return bindDSL;
    }

    private Optional<MethodCallExpr> buildIndexedBy(SingleDrlxParseSuccess drlxParseResult) {
        if (drlxParseResult.isUnification()) {
            TypedExpression left = drlxParseResult.getLeft();
            TypedExpression right = drlxParseResult.getRight();

            LambdaExpr indexedByLeftOperandExtractor = new LambdaExpr();
            indexedByLeftOperandExtractor.setEnclosingParameters(true);
            boolean leftContainsThis = left.getExpression().toString().contains(THIS_PLACEHOLDER);
            TypedExpression typedExpression = leftContainsThis ? left : right;
            indexedByLeftOperandExtractor.addParameter(new Parameter(drlxParseResult.getPatternJPType(), THIS_PLACEHOLDER));
            indexedByLeftOperandExtractor.setBody(new ExpressionStmt(typedExpression.getExpression()));

            MethodCallExpr indexedByDSL = new MethodCallExpr(null, drlxParseResult.isBetaNode() ? BETA_INDEXED_BY_CALL : ALPHA_INDEXED_BY_CALL);
            indexedByDSL.addArgument(new ClassExpr(parseType(getIndexType(left, right ).getCanonicalName())));
            indexedByDSL.addArgument(org.drools.model.Index.ConstraintType.class.getCanonicalName() + ".EQUAL");
            indexedByDSL.addArgument("-1");
            indexedByDSL.addArgument(indexedByLeftOperandExtractor);
            indexedByDSL.addArgument("" + null);
            return Optional.of(indexedByDSL);
        }

        if ( !hasIndex( drlxParseResult ) ) {
            return Optional.empty();
        }

        TypedExpression left = drlxParseResult.getLeft();
        TypedExpression right = drlxParseResult.getRight();

        boolean isBeta = drlxParseResult.isBetaNode();
        if (!isBeta && !(right.getExpression() instanceof LiteralExpr)) {
            return Optional.empty();
        }

        FieldAccessExpr indexedBy_constraintType = new FieldAccessExpr(new NameExpr(org.drools.model.Index.ConstraintType.class.getCanonicalName()), drlxParseResult.getDecodeConstraintType().toString()); // not 100% accurate as the type in "nameExpr" is actually parsed if it was JavaParsers as a big chain of FieldAccessExpr
        LambdaExpr indexedBy_leftOperandExtractor = new LambdaExpr();
        indexedBy_leftOperandExtractor.setEnclosingParameters(true);
        indexedBy_leftOperandExtractor.addParameter(new Parameter(parseClassOrInterfaceType(drlxParseResult.getPatternType().getCanonicalName()), THIS_PLACEHOLDER));
        boolean leftContainsThis = left.getExpression().toString().contains(THIS_PLACEHOLDER);
        indexedBy_leftOperandExtractor.setBody(new ExpressionStmt(leftContainsThis ? left.getExpression() : right.getExpression()));

        MethodCallExpr indexedByDSL = new MethodCallExpr(null, isBeta ? BETA_INDEXED_BY_CALL : ALPHA_INDEXED_BY_CALL);
        indexedByDSL.addArgument(new ClassExpr(parseType(getIndexType(left, right ).getCanonicalName())));
        indexedByDSL.addArgument( indexedBy_constraintType );
        indexedByDSL.addArgument( getIndexIdArgument( drlxParseResult, left ) );
        indexedByDSL.addArgument(indexedBy_leftOperandExtractor );

        Collection<String> usedDeclarations = drlxParseResult.getUsedDeclarations();
        java.lang.reflect.Type leftType = left.getType();
        if ( isAlphaIndex( usedDeclarations )) {
            indexedByDSL.addArgument( narrowExpressionToType(right, left.getType()));
        } else if (usedDeclarations.size() == 1) {
            addIndexedByDeclaration(left, right, leftContainsThis, indexedByDSL, usedDeclarations, leftType, drlxParseResult);
        }
        return Optional.of(indexedByDSL);
    }
}


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Lich. Nov. Zeland. 73 (1888)

#### Original name
Phlyctis andensis Nyl.

### Remarks
null

redpajama_set_name: RedPajamaGithub


text:
package db

import (
	"database/sql"
	"fmt"
	"sort"
	"strings"
	"time"

	"github.com/lxc/lxd/lxd/db/query"
	"github.com/lxc/lxd/shared"
	"github.com/lxc/lxd/shared/api"
	"github.com/pkg/errors"
)

// GetStoragePoolVolumesNames gets the names of all storage volumes attached to
// a given storage pool.
func (c *Cluster) GetStoragePoolVolumesNames(poolID int64) ([]string, error) {
	var volumeName string
	query := "SELECT name FROM storage_volumes_all WHERE storage_pool_id=? AND node_id=?"
	inargs := []interface{}{poolID, c.nodeID}
	outargs := []interface{}{volumeName}

	result, err := queryScan(c, query, inargs, outargs)
	if err != nil {
		return []string{}, err
	}

	var out []string

	for _, r := range result {
		out = append(out, r[0].(string))
	}

	return out, nil
}

// GetStoragePoolVolumesWithType return a list of all volumes of the given type.
func (c *Cluster) GetStoragePoolVolumesWithType(volumeType int) ([]StorageVolumeArgs, error) {
	var id int64
	var name string
	var description string
	var poolName string
	var projectName string

	stmt := `
SELECT storage_volumes.id, storage_volumes.name, storage_volumes.description, storage_pools.name, projects.name
FROM storage_volumes
JOIN storage_pools ON storage_pools.id = storage_volumes.storage_pool_id
JOIN projects ON projects.id = storage_volumes.project_id
WHERE storage_volumes.type = ?
`

	inargs := []interface{}{volumeType}
	outargs := []interface{}{id, name, description, poolName, projectName}

	result, err := queryScan(c, stmt, inargs, outargs)
	if err != nil {
		return nil, err
	}

	var response []StorageVolumeArgs

	for _, r := range result {
		args := StorageVolumeArgs{
			ID:          r[0].(int64),
			Name:        r[1].(string),
			Description: r[2].(string),
			PoolName:    r[3].(string),
			ProjectName: r[4].(string),
		}

		args.Config, err = c.storageVolumeConfigGet(args.ID, false)
		if err != nil {
			return nil, err
		}

		response = append(response, args)
	}

	return response, nil
}

// GetStoragePoolVolumes returns all storage volumes attached to a given
// storage pool on any node. If there are no volumes, it returns an
// empty list and no error.
func (c *Cluster) GetStoragePoolVolumes(project string, poolID int64, volumeTypes []int) ([]*api.StorageVolume, error) {
	var nodeIDs []int

	remoteDrivers := GetRemoteDrivers()

	err := c.Transaction(func(tx *ClusterTx) error {
		var err error
		// Exclude storage volumes residing on ceph and cephfs as their node ID is null, and SelectIntegers() cannot deal with that.

		s := fmt.Sprintf(`
SELECT DISTINCT node_id
  FROM storage_volumes_all
  JOIN projects ON projects.id = storage_volumes_all.project_id
  JOIN storage_pools ON storage_pools.id = storage_volumes_all.storage_pool_id
 WHERE (projects.name=? OR storage_volumes_all.type=?) AND storage_volumes_all.storage_pool_id=? AND storage_pools.driver NOT IN %s`, query.Params(len(remoteDrivers)))

		args := []interface{}{project, StoragePoolVolumeTypeCustom, poolID}

		for _, driver := range remoteDrivers {
			args = append(args, driver)
		}

		nodeIDs, err = query.SelectIntegers(tx.tx, s, args...)
		return err
	})
	if err != nil {
		return nil, err
	}

	volumes := []*api.StorageVolume{}

	for _, nodeID := range nodeIDs {
		nodeVolumes, err := c.storagePoolVolumesGet(project, poolID, int64(nodeID), volumeTypes)
		if err != nil {
			if err == ErrNoSuchObject {
				continue
			}

			return nil, err
		}

		volumes = append(volumes, nodeVolumes...)
	}

	isRemoteStorage, err := c.isRemoteStorage(poolID)
	if err != nil {
		return nil, err
	}

	if isRemoteStorage {
		nodeVolumes, err := c.storagePoolVolumesGet(project, poolID, c.nodeID, volumeTypes)
		if err != nil && err != ErrNoSuchObject {
			return nil, err
		}

		volumes = append(volumes, nodeVolumes...)
	}

	return volumes, nil
}

// GetLocalStoragePoolVolumes returns all storage volumes attached to a given
// storage pool on the current node. If there are no volumes, it returns an
// empty list as well as ErrNoSuchObject.
func (c *Cluster) GetLocalStoragePoolVolumes(project string, poolID int64, volumeTypes []int) ([]*api.StorageVolume, error) {
	return c.storagePoolVolumesGet(project, poolID, c.nodeID, volumeTypes)
}

// Returns all storage volumes attached to a given storage pool on the given
// node. If there are no volumes, it returns an empty list as well as
// ErrNoSuchObject.
func (c *Cluster) storagePoolVolumesGet(project string, poolID, nodeID int64, volumeTypes []int) ([]*api.StorageVolume, error) {
	// Get all storage volumes of all types attached to a given storage pool.
	result := []*api.StorageVolume{}
	for _, volumeType := range volumeTypes {
		volumeNames, err := c.storagePoolVolumesGetType(project, volumeType, poolID, nodeID)
		if err != nil && err != sql.ErrNoRows {
			return nil, errors.Wrap(err, "Failed to fetch volume types")
		}

		for _, volumeName := range volumeNames {
			_, volume, err := c.storagePoolVolumeGetType(project, volumeName, volumeType, poolID, nodeID)
			if err != nil {
				return nil, errors.Wrap(err, "Failed to fetch volume type")
			}
			result = append(result, volume)
		}
	}

	if len(result) == 0 {
		return result, ErrNoSuchObject
	}

	return result, nil
}

// Get all storage volumes attached to a given storage pool of a given volume
// type, on the given node.
func (c *Cluster) storagePoolVolumesGetType(project string, volumeType int, poolID, nodeID int64) ([]string, error) {
	var poolName string

	remoteDrivers := GetRemoteDrivers()

	query := fmt.Sprintf(`
SELECT storage_volumes_all.name
  FROM storage_volumes_all
  JOIN projects ON projects.id=storage_volumes_all.project_id
  join storage_pools ON storage_pools.id=storage_volumes_all.storage_pool_id
 WHERE projects.name=?
   AND storage_volumes_all.storage_pool_id=?
   AND storage_volumes_all.type=?
   AND (storage_volumes_all.node_id=? OR storage_volumes_all.node_id IS NULL AND storage_pools.driver IN %s)`, query.Params(len(remoteDrivers)))
	inargs := []interface{}{project, poolID, volumeType, nodeID}
	outargs := []interface{}{poolName}

	for _, driver := range remoteDrivers {
		inargs = append(inargs, driver)
	}

	result, err := queryScan(c, query, inargs, outargs)
	if err != nil {
		return []string{}, err
	}

	response := []string{}
	for _, r := range result {
		response = append(response, r[0].(string))
	}

	return response, nil
}

// GetLocalStoragePoolVolumeSnapshotsWithType get all snapshots of a storage volume
// attached to a given storage pool of a given volume type, on the local node.
// Returns snapshots slice ordered by when they were created, oldest first.
func (c *Cluster) GetLocalStoragePoolVolumeSnapshotsWithType(projectName string, volumeName string, volumeType int, poolID int64) ([]StorageVolumeArgs, error) {
	result := []StorageVolumeArgs{}
	remoteDrivers := GetRemoteDrivers()

	// ORDER BY id is important here as the users of this function can expect that the results
	// will be returned in the order that the snapshots were created. This is specifically used
	// during migration to ensure that the storage engines can re-create snapshots using the
	// correct deltas.
	query := fmt.Sprintf(`
SELECT storage_volumes_snapshots.name, storage_volumes_snapshots.description FROM storage_volumes_snapshots
  JOIN storage_volumes ON storage_volumes_snapshots.storage_volume_id = storage_volumes.id
  JOIN projects ON projects.id=storage_volumes.project_id
  JOIN storage_pools ON storage_pools.id=storage_volumes.storage_pool_id
  WHERE storage_volumes.storage_pool_id=?
    AND storage_volumes.type=?
    AND storage_volumes.name=?
    AND projects.name=?
    AND (storage_volumes.node_id=? OR storage_volumes.node_id IS NULL AND storage_pools.driver IN %s)
  ORDER BY storage_volumes_snapshots.id`, query.Params(len(remoteDrivers)))
	inargs := []interface{}{poolID, volumeType, volumeName, projectName, c.nodeID}

	for _, driver := range remoteDrivers {
		inargs = append(inargs, driver)
	}

	typeGuide := StorageVolumeArgs{} // StorageVolume struct used to guide the types expected.
	outfmt := []interface{}{typeGuide.Name, typeGuide.Description}
	dbResults, err := queryScan(c, query, inargs, outfmt)
	if err != nil {
		return result, err
	}

	for _, r := range dbResults {
		row := StorageVolumeArgs{
			Name:        volumeName + shared.SnapshotDelimiter + r[0].(string),
			Description: r[1].(string),
		}
		result = append(result, row)
	}

	return result, nil
}

// GetLocalStoragePoolVolumesWithType returns all storage volumes attached to a
// given storage pool of a given volume type, on the current node.
func (c *Cluster) GetLocalStoragePoolVolumesWithType(projectName string, volumeType int, poolID int64) ([]string, error) {
	return c.storagePoolVolumesGetType(projectName, volumeType, poolID, c.nodeID)
}

// Return a single storage volume attached to a given storage pool of a given
// type, on the node with the given ID.
func (c *Cluster) storagePoolVolumeGetType(project string, volumeName string, volumeType int, poolID, nodeID int64) (int64, *api.StorageVolume, error) {
	isSnapshot := strings.Contains(volumeName, shared.SnapshotDelimiter)

	volumeID, err := c.storagePoolVolumeGetTypeID(project, volumeName, volumeType, poolID, nodeID)
	if err != nil {
		return -1, nil, err
	}

	isRemoteStorage, err := c.isRemoteStorage(poolID)
	if err != nil {
		return -1, nil, err
	}

	volumeNode := ""

	if !isRemoteStorage {
		volumeNode, err = c.storageVolumeNodeGet(volumeID)
		if err != nil {
			return -1, nil, err
		}
	}

	volumeConfig, err := c.storageVolumeConfigGet(volumeID, isSnapshot)
	if err != nil {
		return -1, nil, err
	}

	volumeDescription, err := c.GetStorageVolumeDescription(volumeID)
	if err != nil {
		return -1, nil, err
	}

	volumeContentType, err := c.getStorageVolumeContentType(volumeID)
	if err != nil {
		return -1, nil, err
	}

	volumeTypeName, err := storagePoolVolumeTypeToName(volumeType)
	if err != nil {
		return -1, nil, err
	}

	volumeContentTypeName, err := storagePoolVolumeContentTypeToName(volumeContentType)
	if err != nil {
		return -1, nil, err
	}

	storageVolume := api.StorageVolume{
		Type: volumeTypeName,
	}
	storageVolume.Name = volumeName
	storageVolume.Description = volumeDescription
	storageVolume.Config = volumeConfig
	storageVolume.Location = volumeNode
	storageVolume.ContentType = volumeContentTypeName

	return volumeID, &storageVolume, nil
}

// GetLocalStoragePoolVolume gets a single storage volume attached to a
// given storage pool of a given type, on the current node in the given project.
func (c *Cluster) GetLocalStoragePoolVolume(project, volumeName string, volumeType int, poolID int64) (int64, *api.StorageVolume, error) {
	return c.storagePoolVolumeGetType(project, volumeName, volumeType, poolID, c.nodeID)
}

// UpdateStoragePoolVolume updates the storage volume attached to a given storage pool.
func (c *Cluster) UpdateStoragePoolVolume(project, volumeName string, volumeType int, poolID int64, volumeDescription string, volumeConfig map[string]string) error {
	volumeID, _, err := c.GetLocalStoragePoolVolume(project, volumeName, volumeType, poolID)
	if err != nil {
		return err
	}

	isSnapshot := strings.Contains(volumeName, shared.SnapshotDelimiter)

	err = c.Transaction(func(tx *ClusterTx) error {
		err = storagePoolVolumeReplicateIfCeph(tx.tx, volumeID, project, volumeName, volumeType, poolID, func(volumeID int64) error {
			err = storageVolumeConfigClear(tx.tx, volumeID, isSnapshot)
			if err != nil {
				return err
			}

			err = storageVolumeConfigAdd(tx.tx, volumeID, volumeConfig, isSnapshot)
			if err != nil {
				return err
			}

			return storageVolumeDescriptionUpdate(tx.tx, volumeID, volumeDescription, isSnapshot)
		})
		if err != nil {
			return err
		}
		return nil
	})

	return err
}

// RemoveStoragePoolVolume deletes the storage volume attached to a given storage
// pool.
func (c *Cluster) RemoveStoragePoolVolume(project, volumeName string, volumeType int, poolID int64) error {
	volumeID, _, err := c.GetLocalStoragePoolVolume(project, volumeName, volumeType, poolID)
	if err != nil {
		return err
	}

	isSnapshot := strings.Contains(volumeName, shared.SnapshotDelimiter)
	var stmt string
	if isSnapshot {
		stmt = "DELETE FROM storage_volumes_snapshots WHERE id=?"
	} else {
		stmt = "DELETE FROM storage_volumes WHERE id=?"
	}

	err = c.Transaction(func(tx *ClusterTx) error {
		err := storagePoolVolumeReplicateIfCeph(tx.tx, volumeID, project, volumeName, volumeType, poolID, func(volumeID int64) error {
			_, err := tx.tx.Exec(stmt, volumeID)
			return err
		})
		return err
	})

	return err
}

// RenameStoragePoolVolume renames the storage volume attached to a given storage pool.
func (c *Cluster) RenameStoragePoolVolume(project, oldVolumeName string, newVolumeName string, volumeType int, poolID int64) error {
	volumeID, _, err := c.GetLocalStoragePoolVolume(project, oldVolumeName, volumeType, poolID)
	if err != nil {
		return err
	}

	isSnapshot := strings.Contains(oldVolumeName, shared.SnapshotDelimiter)
	var stmt string
	if isSnapshot {
		parts := strings.Split(newVolumeName, shared.SnapshotDelimiter)
		newVolumeName = parts[1]
		stmt = "UPDATE storage_volumes_snapshots SET name=? WHERE id=?"
	} else {
		stmt = "UPDATE storage_volumes SET name=? WHERE id=?"
	}

	err = c.Transaction(func(tx *ClusterTx) error {
		err := storagePoolVolumeReplicateIfCeph(tx.tx, volumeID, project, oldVolumeName, volumeType, poolID, func(volumeID int64) error {
			_, err := tx.tx.Exec(stmt, newVolumeName, volumeID)
			return err
		})
		return err
	})

	return err
}

// This a convenience to replicate a certain volume change to all nodes if the
// underlying driver is ceph.
func storagePoolVolumeReplicateIfCeph(tx *sql.Tx, volumeID int64, project, volumeName string, volumeType int, poolID int64, f func(int64) error) error {
	driver, err := storagePoolDriverGet(tx, poolID)
	if err != nil {
		return err
	}
	volumeIDs := []int64{volumeID}

	remoteDrivers := GetRemoteDrivers()

	// If this is a ceph volume, we want to duplicate the change across the
	// the rows for all other nodes.
	if shared.StringInSlice(driver, remoteDrivers) {
		volumeIDs, err = storageVolumeIDsGet(tx, project, volumeName, volumeType, poolID)
		if err != nil {
			return err
		}
	}

	for _, volumeID := range volumeIDs {
		err := f(volumeID)
		if err != nil {
			return err
		}
	}

	return nil
}

// CreateStoragePoolVolume creates a new storage volume attached to a given
// storage pool.
func (c *Cluster) CreateStoragePoolVolume(project, volumeName, volumeDescription string, volumeType int, poolID int64, volumeConfig map[string]string, contentType int) (int64, error) {
	var volumeID int64

	if shared.IsSnapshot(volumeName) {
		return -1, fmt.Errorf("Volume name may not be a snapshot")
	}

	remoteDrivers := GetRemoteDrivers()

	err := c.Transaction(func(tx *ClusterTx) error {
		driver, err := tx.GetStoragePoolDriver(poolID)
		if err != nil {
			return err
		}

		var result sql.Result

		if shared.StringInSlice(driver, remoteDrivers) {
			result, err = tx.tx.Exec(`
INSERT INTO storage_volumes (storage_pool_id, type, name, description, project_id, content_type)
 VALUES (?, ?, ?, ?, (SELECT id FROM projects WHERE name = ?), ?)
`,
				poolID, volumeType, volumeName, volumeDescription, project, contentType)
		} else {
			result, err = tx.tx.Exec(`
INSERT INTO storage_volumes (storage_pool_id, node_id, type, name, description, project_id, content_type)
 VALUES (?, ?, ?, ?, ?, (SELECT id FROM projects WHERE name = ?), ?)
`,
				poolID, c.nodeID, volumeType, volumeName, volumeDescription, project, contentType)
		}
		if err != nil {
			return err
		}

		volumeID, err = result.LastInsertId()
		if err != nil {
			return err
		}

		err = storageVolumeConfigAdd(tx.tx, volumeID, volumeConfig, false)
		if err != nil {
			return errors.Wrap(err, "Insert storage volume configuration")
		}

		return nil
	})
	if err != nil {
		volumeID = -1
	}

	return volumeID, err
}

// Return the ID of a storage volume on a given storage pool of a given storage
// volume type, on the given node.
func (c *Cluster) storagePoolVolumeGetTypeID(project string, volumeName string, volumeType int, poolID, nodeID int64) (int64, error) {
	var id int64
	err := c.Transaction(func(tx *ClusterTx) error {
		var err error
		id, err = tx.storagePoolVolumeGetTypeID(project, volumeName, volumeType, poolID, nodeID)
		return err
	})
	if err != nil {
		return -1, err
	}
	return id, nil
}

func (c *ClusterTx) storagePoolVolumeGetTypeID(project string, volumeName string, volumeType int, poolID, nodeID int64) (int64, error) {
	remoteDrivers := GetRemoteDrivers()

	s := fmt.Sprintf(`
SELECT storage_volumes_all.id
  FROM storage_volumes_all
  JOIN storage_pools ON storage_volumes_all.storage_pool_id = storage_pools.id
  JOIN projects ON storage_volumes_all.project_id = projects.id
  WHERE projects.name=?
    AND storage_volumes_all.storage_pool_id=?
    AND storage_volumes_all.name=?
	AND storage_volumes_all.type=?
	AND (storage_volumes_all.node_id=? OR storage_volumes_all.node_id IS NULL AND storage_pools.driver IN %s)`, query.Params(len(remoteDrivers)))

	args := []interface{}{project, poolID, volumeName, volumeType, nodeID}

	for _, driver := range remoteDrivers {
		args = append(args, driver)
	}

	result, err := query.SelectIntegers(c.tx, s, args...)
	if err != nil {
		return -1, err
	}

	if len(result) == 0 {
		return -1, ErrNoSuchObject
	}

	return int64(result[0]), nil
}

// GetStoragePoolNodeVolumeID gets the ID of a storage volume on a given storage pool
// of a given storage volume type and project, on the current node.
func (c *Cluster) GetStoragePoolNodeVolumeID(projectName string, volumeName string, volumeType int, poolID int64) (int64, error) {
	return c.storagePoolVolumeGetTypeID(projectName, volumeName, volumeType, poolID, c.nodeID)
}

// XXX: this was extracted from lxd/storage_volume_utils.go, we find a way to
//      factor it independently from both the db and main packages.
const (
	StoragePoolVolumeTypeContainer = iota
	StoragePoolVolumeTypeImage
	StoragePoolVolumeTypeCustom
	StoragePoolVolumeTypeVM
)

// Leave the string type in here! This guarantees that go treats this is as a
// typed string constant. Removing it causes go to treat these as untyped string
// constants which is not what we want.
const (
	StoragePoolVolumeTypeNameContainer string = "container"
	StoragePoolVolumeTypeNameVM        string = "virtual-machine"
	StoragePoolVolumeTypeNameImage     string = "image"
	StoragePoolVolumeTypeNameCustom    string = "custom"
)

// Content types.
const (
	StoragePoolVolumeContentTypeFS = iota
	StoragePoolVolumeContentTypeBlock
)

// Content type names.
const (
	StoragePoolVolumeContentTypeNameFS    string = "filesystem"
	StoragePoolVolumeContentTypeNameBlock string = "block"
)

// StorageVolumeArgs is a value object holding all db-related details about a
// storage volume.
type StorageVolumeArgs struct {
	ID   int64
	Name string

	// At least one of Type or TypeName must be set.
	Type     int
	TypeName string

	// At least one of PoolID or PoolName must be set.
	PoolID   int64
	PoolName string

	Snapshot bool

	Config       map[string]string
	Description  string
	CreationDate time.Time
	ExpiryDate   time.Time

	// At least on of ProjectID or ProjectName must be set.
	ProjectID   int64
	ProjectName string

	ContentType string
}

// GetStorageVolumeNodeAddresses returns the addresses of all nodes on which the
// volume with the given name if defined.
//
// The volume name can be either a regular name or a volume snapshot name.
//
// The empty string is used in place of the address of the current node.
func (c *ClusterTx) GetStorageVolumeNodeAddresses(poolID int64, project, name string, typ int) ([]string, error) {
	nodes := []struct {
		id      int64
		address string
	}{}
	dest := func(i int) []interface{} {
		nodes = append(nodes, struct {
			id      int64
			address string
		}{})
		return []interface{}{&nodes[i].id, &nodes[i].address}

	}
	sql := `
SELECT nodes.id, nodes.address
  FROM nodes
  JOIN storage_volumes_all ON storage_volumes_all.node_id=nodes.id
  JOIN projects ON projects.id = storage_volumes_all.project_id
 WHERE storage_volumes_all.storage_pool_id=?
   AND projects.name=?
   AND storage_volumes_all.name=?
   AND storage_volumes_all.type=?
`
	stmt, err := c.tx.Prepare(sql)
	if err != nil {
		return nil, err
	}
	defer stmt.Close()
	err = query.SelectObjects(stmt, dest, poolID, project, name, typ)
	if err != nil {
		return nil, err
	}

	addresses := []string{}
	for _, node := range nodes {
		address := node.address
		if node.id == c.nodeID {
			address = ""
		}
		addresses = append(addresses, address)
	}

	sort.Strings(addresses)

	if len(addresses) == 0 {
		return nil, ErrNoSuchObject
	}

	return addresses, nil
}

// Return the name of the node a storage volume is on.
func (c *Cluster) storageVolumeNodeGet(volumeID int64) (string, error) {
	name := ""
	query := `
SELECT nodes.name FROM storage_volumes_all
  JOIN nodes ON nodes.id=storage_volumes_all.node_id
   WHERE storage_volumes_all.id=?
`
	inargs := []interface{}{volumeID}
	outargs := []interface{}{&name}

	err := dbQueryRowScan(c, query, inargs, outargs)
	if err != nil {
		if err == sql.ErrNoRows {
			return "", ErrNoSuchObject
		}

		return "", err
	}

	return name, nil
}

// Get the config of a storage volume.
func (c *Cluster) storageVolumeConfigGet(volumeID int64, isSnapshot bool) (map[string]string, error) {
	var key, value string
	var query string
	if isSnapshot {
		query = "SELECT key, value FROM storage_volumes_snapshots_config WHERE storage_volume_snapshot_id=?"
	} else {
		query = "SELECT key, value FROM storage_volumes_config WHERE storage_volume_id=?"
	}
	inargs := []interface{}{volumeID}
	outargs := []interface{}{key, value}

	results, err := queryScan(c, query, inargs, outargs)
	if err != nil {
		return nil, err
	}

	config := map[string]string{}

	for _, r := range results {
		key = r[0].(string)
		value = r[1].(string)

		config[key] = value
	}

	return config, nil
}

// GetStorageVolumeDescription gets the description of a storage volume.
func (c *Cluster) GetStorageVolumeDescription(volumeID int64) (string, error) {
	description := sql.NullString{}
	query := "SELECT description FROM storage_volumes_all WHERE id=?"
	inargs := []interface{}{volumeID}
	outargs := []interface{}{&description}

	err := dbQueryRowScan(c, query, inargs, outargs)
	if err != nil {
		if err == sql.ErrNoRows {
			return "", ErrNoSuchObject
		}
		return "", err
	}

	return description.String, nil
}

// getStorageVolumeContentType gets the content type of a storage volume.
func (c *Cluster) getStorageVolumeContentType(volumeID int64) (int, error) {
	var contentType int
	query := "SELECT content_type FROM storage_volumes_all WHERE id=?"
	inargs := []interface{}{volumeID}
	outargs := []interface{}{&contentType}

	err := dbQueryRowScan(c, query, inargs, outargs)
	if err != nil {
		if err == sql.ErrNoRows {
			return -1, ErrNoSuchObject
		}
		return -1, err
	}

	return contentType, nil
}

// GetNextStorageVolumeSnapshotIndex returns the index of the next snapshot of the storage
// volume with the given name should have.
//
// Note, the code below doesn't deal with snapshots of snapshots.
// To do that, we'll need to weed out based on # slashes in names
func (c *Cluster) GetNextStorageVolumeSnapshotIndex(pool, name string, typ int, pattern string) int {
	q := fmt.Sprintf(`
SELECT storage_volumes_snapshots.name FROM storage_volumes_snapshots
  JOIN storage_volumes ON storage_volumes_snapshots.storage_volume_id=storage_volumes.id
  JOIN storage_pools ON storage_volumes.storage_pool_id=storage_pools.id
 WHERE storage_volumes.type=?
   AND storage_volumes.name=?
   AND storage_pools.name=?
`)
	var numstr string
	inargs := []interface{}{typ, name, pool}
	outfmt := []interface{}{numstr}
	results, err := queryScan(c, q, inargs, outfmt)
	if err != nil {
		return 0
	}
	max := 0

	for _, r := range results {
		substr := r[0].(string)
		fields := strings.SplitN(pattern, "%d", 2)

		var num int
		count, err := fmt.Sscanf(substr, fmt.Sprintf("%s%%d%s", fields[0], fields[1]), &num)
		if err != nil || count != 1 {
			continue
		}
		if num >= max {
			max = num + 1
		}
	}

	return max
}

// StorageVolumeIsAvailable checks that if a custom volume available for being attached.
//
// Always return true for non-Ceph volumes.
//
// For Ceph volumes, return true if the volume is either not attached to any
// other container, or attached to containers on this node.
func (c *Cluster) StorageVolumeIsAvailable(pool, volume string) (bool, error) {
	isAvailable := false

	err := c.Transaction(func(tx *ClusterTx) error {
		id, err := tx.GetStoragePoolID(pool)
		if err != nil {
			return errors.Wrapf(err, "Fetch storage pool ID for %q", pool)
		}

		driver, err := tx.GetStoragePoolDriver(id)
		if err != nil {
			return errors.Wrapf(err, "Fetch storage pool driver for %q", pool)
		}

		if driver != "ceph" {
			isAvailable = true
			return nil
		}

		node, err := tx.GetLocalNodeName()
		if err != nil {
			return errors.Wrapf(err, "Fetch node name")
		}

		containers, err := tx.instanceListExpanded()
		if err != nil {
			return errors.Wrapf(err, "Fetch instances")
		}

		for _, container := range containers {
			for _, device := range container.Devices {
				if device["type"] != "disk" {
					continue
				}
				if device["pool"] != pool {
					continue
				}
				if device["source"] != volume {
					continue
				}
				if container.Node != node {
					// This ceph volume is already attached
					// to a container on a different node.
					return nil
				}
			}
		}
		isAvailable = true

		return nil
	})
	if err != nil {
		return false, err
	}

	return isAvailable, nil
}

// Updates the description of a storage volume.
func storageVolumeDescriptionUpdate(tx *sql.Tx, volumeID int64, description string, isSnapshot bool) error {
	var table string
	if isSnapshot {
		table = "storage_volumes_snapshots"
	} else {
		table = "storage_volumes"
	}
	stmt := fmt.Sprintf("UPDATE %s SET description=? WHERE id=?", table)
	_, err := tx.Exec(stmt, description, volumeID)
	return err
}

// Add a new storage volume config into database.
func storageVolumeConfigAdd(tx *sql.Tx, volumeID int64, volumeConfig map[string]string, isSnapshot bool) error {
	var str string
	if isSnapshot {
		str = "INSERT INTO storage_volumes_snapshots_config (storage_volume_snapshot_id, key, value) VALUES(?, ?, ?)"
	} else {
		str = "INSERT INTO storage_volumes_config (storage_volume_id, key, value) VALUES(?, ?, ?)"
	}
	stmt, err := tx.Prepare(str)
	defer stmt.Close()
	if err != nil {
		return err
	}

	for k, v := range volumeConfig {
		if v == "" {
			continue
		}

		_, err = stmt.Exec(volumeID, k, v)
		if err != nil {
			return err
		}
	}

	return nil
}

// Delete storage volume config.
func storageVolumeConfigClear(tx *sql.Tx, volumeID int64, isSnapshot bool) error {
	var stmt string
	if isSnapshot {
		stmt = "DELETE FROM storage_volumes_snapshots_config WHERE storage_volume_snapshot_id=?"
	} else {
		stmt = "DELETE FROM storage_volumes_config WHERE storage_volume_id=?"
	}
	_, err := tx.Exec(stmt, volumeID)
	if err != nil {
		return err
	}

	return nil
}

// Get the IDs of all volumes with the given name and type associated with the
// given pool, regardless of their node_id column.
func storageVolumeIDsGet(tx *sql.Tx, project, volumeName string, volumeType int, poolID int64) ([]int64, error) {
	ids, err := query.SelectIntegers(tx, `
SELECT storage_volumes_all.id
  FROM storage_volumes_all
  JOIN projects ON projects.id = storage_volumes_all.project_id
 WHERE projects.name=?
   AND storage_volumes_all.name=?
   AND storage_volumes_all.type=?
   AND storage_volumes_all.storage_pool_id=?
`, project, volumeName, volumeType, poolID)
	if err != nil {
		return nil, err
	}
	ids64 := make([]int64, len(ids))
	for i, id := range ids {
		ids64[i] = int64(id)
	}
	return ids64, nil
}

// RemoveStorageVolumeImages removes the volumes associated with the images
// with the given fingerprints.
func (c *Cluster) RemoveStorageVolumeImages(fingerprints []string) error {
	stmt := fmt.Sprintf(
		"DELETE FROM storage_volumes WHERE type=? AND name NOT IN %s",
		query.Params(len(fingerprints)))
	args := []interface{}{StoragePoolVolumeTypeImage}
	for _, fingerprint := range fingerprints {
		args = append(args, fingerprint)
	}
	err := exec(c, stmt, args...)
	return err
}

// UpgradeStorageVolumConfigToLVMThinPoolNameKey upgrades the config keys of LVM
// volumes.
func (c *Cluster) UpgradeStorageVolumConfigToLVMThinPoolNameKey() error {
	err := exec(c, "UPDATE storage_pools_config SET key='lvm.thinpool_name' WHERE key='volume.lvm.thinpool_name';")
	if err != nil {
		return err
	}

	err = exec(c, "DELETE FROM storage_volumes_config WHERE key='lvm.thinpool_name';")
	if err != nil {
		return err
	}
	err = exec(c, "DELETE FROM storage_volumes_snapshots_config WHERE key='lvm.thinpool_name';")
	if err != nil {
		return err
	}

	return nil
}

// Convert a volume integer type code to its human-readable name.
func storagePoolVolumeTypeToName(volumeType int) (string, error) {
	switch volumeType {
	case StoragePoolVolumeTypeContainer:
		return StoragePoolVolumeTypeNameContainer, nil
	case StoragePoolVolumeTypeVM:
		return StoragePoolVolumeTypeNameVM, nil
	case StoragePoolVolumeTypeImage:
		return StoragePoolVolumeTypeNameImage, nil
	case StoragePoolVolumeTypeCustom:
		return StoragePoolVolumeTypeNameCustom, nil
	}

	return "", fmt.Errorf("Invalid storage volume type")
}

// Convert a volume integer content type code to its human-readable name.
func storagePoolVolumeContentTypeToName(contentType int) (string, error) {
	switch contentType {
	case StoragePoolVolumeContentTypeFS:
		return StoragePoolVolumeContentTypeNameFS, nil
	case StoragePoolVolumeContentTypeBlock:
		return StoragePoolVolumeContentTypeNameBlock, nil
	}

	return "", fmt.Errorf("Invalid storage volume content type")
}

// GetCustomVolumesInProject returns all custom volumes in the given project.
func (c *ClusterTx) GetCustomVolumesInProject(project string) ([]StorageVolumeArgs, error) {
	sql := `
SELECT storage_volumes.id, storage_volumes.name, storage_pools.name
FROM storage_volumes
JOIN storage_pools ON storage_pools.id = storage_volumes.storage_pool_id
JOIN projects ON projects.id = storage_volumes.project_id
WHERE storage_volumes.type = ? AND projects.name = ?
`
	stmt, err := c.tx.Prepare(sql)
	if err != nil {
		return nil, err
	}
	defer stmt.Close()

	volumes := []StorageVolumeArgs{}
	dest := func(i int) []interface{} {
		volumes = append(volumes, StorageVolumeArgs{})
		return []interface{}{
			&volumes[i].ID,
			&volumes[i].Name,
			&volumes[i].PoolName,
		}
	}

	err = query.SelectObjects(stmt, dest, StoragePoolVolumeTypeCustom, project)
	if err != nil {
		return nil, errors.Wrap(err, "Fetch custom volumes")
	}

	for i, volume := range volumes {
		config, err := query.SelectConfig(c.tx, "storage_volumes_config", "storage_volume_id=?", volume.ID)
		if err != nil {
			return nil, errors.Wrap(err, "Fetch custom volume config")
		}
		volumes[i].Config = config
	}

	return volumes, nil
}


text:
package com.lanian.bttestpc;

import java.io.IOException;

import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnectionNotifier;

public class BluetoothServer implements Runnable {

	private final UUID SERVER_UUID = new UUID("c9faf940e20c11e39ffa0002a5d5c51b", false);

	private final String url = "btspp://localhost:"+SERVER_UUID.toString()+";name=SimpleBluetoohServer;";

	@Override
	public void run() {
		listen();
		System.err.println("bluetooth server stopped.");
	}

	private boolean listen() {

		try {
			LocalDevice.getLocalDevice().setDiscoverable(DiscoveryAgent.GIAC);
		} catch (BluetoothStateException e1) {
			e1.printStackTrace();
		}

		StreamConnectionNotifier notifier;
		try {
			notifier = (StreamConnectionNotifier) Connector.open(url);
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}

		while (notifier != null) {
			System.out.println(String.format("listening on %s", url));
			try {
				new Thread(new CommandProcessor(notifier.acceptAndOpen())).start();
			} catch (IOException e) {
				e.printStackTrace();
				return false;
			}
		}

		return true;
	}

}


text:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Design;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Reflection;
using System.Runtime.InteropServices;
namespace JAJ.WinForm.Comm
{
    /// <summary>
    /// DataGridView行合并.请对属性MergeColumnNames 赋值既可
    /// </summary>
    public partial class DataGridViewExt : DataGridView
    {
        #region 构造函数
        public DataGridViewExt()
        {
            InitializeComponent();
        }
        #endregion

        #region 重写的事件
        protected override void OnPaint(PaintEventArgs pe)
        {
            // TODO: 在此处添加自定义绘制代码

            // 调用基类 OnPaint
            base.OnPaint(pe);
        }
        protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
        {
            try
            {
                if (e.RowIndex > -1 && e.ColumnIndex > -1)
                {
                    DrawCell(e);
                }
                else
                {
                    //二维表头
                    if (e.RowIndex == -1)
                    {
                        if (SpanRows.ContainsKey(e.ColumnIndex)) //被合并的列
                        {
                            //画边框
                            Graphics g = e.Graphics;
                            e.Paint(e.CellBounds, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);

                            int left = e.CellBounds.Left, top = e.CellBounds.Top + 2,
                            right = e.CellBounds.Right, bottom = e.CellBounds.Bottom;

                            switch (SpanRows[e.ColumnIndex].Position)
                            {
                                case 1:
                                    left += 2;
                                    break;
                                case 2:
                                    break;
                                case 3:
                                    right -= 2;
                                    break;
                            }

                            //画上半部分底色
                            g.FillRectangle(new SolidBrush(this._mergecolumnheaderbackcolor), left, top,
                            right - left, (bottom - top) / 2);

                            //画中线
                            g.DrawLine(new Pen(this.GridColor), left, (top + bottom) / 2,
                            right, (top + bottom) / 2);

                            //写小标题
                            StringFormat sf = new StringFormat();
                            sf.Alignment = StringAlignment.Center;
                            sf.LineAlignment = StringAlignment.Center;

                            g.DrawString(e.Value + "", e.CellStyle.Font, Brushes.Black,
                            new Rectangle(left, (top + bottom) / 2, right - left, (bottom - top) / 2), sf);
                            left = this.GetColumnDisplayRectangle(SpanRows[e.ColumnIndex].Left, true).Left - 2;

                            if (left < 0) left = this.GetCellDisplayRectangle(-1, -1, true).Width;
                            right = this.GetColumnDisplayRectangle(SpanRows[e.ColumnIndex].Right, true).Right - 2;
                            if (right < 0) right = this.Width;

                            g.DrawString(SpanRows[e.ColumnIndex].Text, e.CellStyle.Font, Brushes.Black,
                            new Rectangle(left, top, right - left, (bottom - top) / 2), sf);
                            e.Handled = true;
                        }
                    }
                }
                base.OnCellPainting(e);
            }
            catch
            { }
        }
        protected override void OnCellClick(DataGridViewCellEventArgs e)
        {
            base.OnCellClick(e);
        }
        #endregion

        #region 自定义方法
        /// <summary>
        /// 画单元格
        /// </summary>
        /// <param name="e"></param>
        private void DrawCell(DataGridViewCellPaintingEventArgs e)
        {
            if (e.CellStyle.Alignment == DataGridViewContentAlignment.NotSet)
            {
                e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            }
            Brush gridBrush = new SolidBrush(this.GridColor);
            SolidBrush backBrush = new SolidBrush(e.CellStyle.BackColor);
            SolidBrush fontBrush = new SolidBrush(e.CellStyle.ForeColor);
            int cellwidth;
            //上面相同的行数
            int UpRows = 0;
            //下面相同的行数
            int DownRows = 0;
            //总行数
            int count = 0;
            if (this.MergeColumnNames.Contains(this.Columns[e.ColumnIndex].Name) && e.RowIndex != -1)
            {
                cellwidth = e.CellBounds.Width;
                Pen gridLinePen = new Pen(gridBrush);
                string curValue = e.Value == null ? "" : e.Value.ToString().Trim();
                string curSelected = this.CurrentRow.Cells[e.ColumnIndex].Value == null ? "" : this.CurrentRow.Cells[e.ColumnIndex].Value.ToString().Trim();
                if (!string.IsNullOrEmpty(curValue))
                {
                    #region 获取下面的行数
                    for (int i = e.RowIndex; i < this.Rows.Count; i++)
                    {
                        if (this.Rows[i].Cells[e.ColumnIndex].Value.ToString().Equals(curValue))
                        {
                            //this.Rows[i].Cells[e.ColumnIndex].Selected = this.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected;

                            DownRows++;
                            if (e.RowIndex != i)
                            {
                                cellwidth = cellwidth < this.Rows[i].Cells[e.ColumnIndex].Size.Width ? cellwidth : this.Rows[i].Cells[e.ColumnIndex].Size.Width;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    #endregion
                    #region 获取上面的行数
                    for (int i = e.RowIndex; i >= 0; i--)
                    {
                        if (this.Rows[i].Cells[e.ColumnIndex].Value.ToString().Equals(curValue))
                        {
                            //this.Rows[i].Cells[e.ColumnIndex].Selected = this.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected;
                            UpRows++;
                            if (e.RowIndex != i)
                            {
                                cellwidth = cellwidth < this.Rows[i].Cells[e.ColumnIndex].Size.Width ? cellwidth : this.Rows[i].Cells[e.ColumnIndex].Size.Width;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    #endregion
                    count = DownRows + UpRows - 1;
                    if (count < 2)
                    {
                        return;
                    }
                }
                if (this.Rows[e.RowIndex].Selected)
                {
                    backBrush.Color = e.CellStyle.SelectionBackColor;
                    fontBrush.Color = e.CellStyle.SelectionForeColor;
                }
                //以背景色填充
                e.Graphics.FillRectangle(backBrush, e.CellBounds);
                //画字符串
                PaintingFont(e, cellwidth, UpRows, DownRows, count);
                if (DownRows == 1)
                {
                    e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);
                    count = 0;
                }
                // 画右边线
                e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1, e.CellBounds.Top, e.CellBounds.Right - 1, e.CellBounds.Bottom);

                e.Handled = true;
            }
        }
        /// <summary>
        /// 画字符串
        /// </summary>
        /// <param name="e"></param>
        /// <param name="cellwidth"></param>
        /// <param name="UpRows"></param>
        /// <param name="DownRows"></param>
        /// <param name="count"></param>
        private void PaintingFont(System.Windows.Forms.DataGridViewCellPaintingEventArgs e, int cellwidth, int UpRows, int DownRows, int count)
        {
            SolidBrush fontBrush = new SolidBrush(e.CellStyle.ForeColor);
            int fontheight = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Height;
            int fontwidth = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Width;
            int cellheight = e.CellBounds.Height;

            if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomCenter)
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y + cellheight * DownRows - fontheight);
            }
            else if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomLeft)
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y + cellheight * DownRows - fontheight);
            }
            else if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomRight)
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y + cellheight * DownRows - fontheight);
            }
            else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleCenter)
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2);
            }
            else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleLeft)
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2);
            }
            else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleRight)
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2);
            }
            else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopCenter)
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1));
            }
            else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopLeft)
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y - cellheight * (UpRows - 1));
            }
            else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopRight)
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y - cellheight * (UpRows - 1));
            }
            else
            {
                e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2);
            }
        }
        #endregion

        #region 属性
        /// <summary>
        /// 设置或获取合并列的集合
        /// </summary>
        [MergableProperty(false)]
        [Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
        [DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Visible)]
        [Localizable(true)]
        [Description("设置或获取合并列的集合"), Browsable(true), Category("单元格合并")]
        public List<string> MergeColumnNames
        {
            get
            {
                return _mergecolumnname;
            }
            set
            {
                _mergecolumnname = value;
            }
        }
        private List<string> _mergecolumnname = new List<string>();
        #endregion

        #region 二维表头
        private struct SpanInfo //表头信息
        {
            public SpanInfo(string Text, int Position, int Left, int Right)
            {
                this.Text = Text;
                this.Position = Position;
                this.Left = Left;
                this.Right = Right;
            }

            public string Text; //列主标题
            public int Position; //位置,1:左,2中,3右
            public int Left; //对应左行
            public int Right; //对应右行
        }
        private Dictionary<int, SpanInfo> SpanRows = new Dictionary<int, SpanInfo>();//需要2维表头的列
        /// <summary>
        /// 合并列
        /// </summary>
        /// <param name="ColIndex">列的索引</param>
        /// <param name="ColCount">需要合并的列数</param>
        /// <param name="Text">合并列后的文本</param>
        public void AddSpanHeader(int ColIndex, int ColCount, string Text)
        {
            if (ColCount < 2)
            {
                throw new Exception("行宽应大于等于2,合并1列无意义。");
            }
            //将这些列加入列表
            int Right = ColIndex + ColCount - 1; //同一大标题下的最后一列的索引
            SpanRows[ColIndex] = new SpanInfo(Text, 1, ColIndex, Right); //添加标题下的最左列
            SpanRows[Right] = new SpanInfo(Text, 3, ColIndex, Right); //添加该标题下的最右列
            for (int i = ColIndex + 1; i < Right; i++) //中间的列
            {
                SpanRows[i] = new SpanInfo(Text, 2, ColIndex, Right);
            }
        }
        /// <summary>
        /// 清除合并的列
        /// </summary>
        public void ClearSpanInfo()
        {
            SpanRows.Clear();
            //ReDrawHead();
        }
        private void DataGridViewEx_Scroll(object sender, ScrollEventArgs e)
        {
            if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll)// && e.Type == ScrollEventType.EndScroll)
            {
                timer1.Enabled = false; timer1.Enabled = true;
            }
        }
        //刷新显示表头
        public void ReDrawHead()
        {
            foreach (int si in SpanRows.Keys)
            {
                this.Invalidate(this.GetCellDisplayRectangle(si, -1, true));
            }
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            timer1.Enabled = false;
            ReDrawHead();
        }
        /// <summary>
        /// 二维表头的背景颜色
        /// </summary>
        [Description("二维表头的背景颜色"), Browsable(true), Category("二维表头")]
        public Color MergeColumnHeaderBackColor
        {
            get { return this._mergecolumnheaderbackcolor; }
            set { this._mergecolumnheaderbackcolor = value; }
        }
        private Color _mergecolumnheaderbackcolor = System.Drawing.SystemColors.Control;
        #endregion
    }

}


text:
var EXPECTED_NAME = 'Auto-Update Test';

chrome.management.getAll(function(items) {
  for (var i = 0; i < items.length; i++) {
    var item = items[i];
    if (item.name != EXPECTED_NAME) continue;
    var id = item.id;
    chrome.test.assertEq(false, item.mayDisable);
    chrome.test.runWithUserGesture(function() {
      chrome.management.uninstall(id, function() {
        // Check that the right error occured.
        var expectedError = 'Extension ' + id + ' cannot be modified by user.';
        chrome.test.assertEq(expectedError, chrome.runtime.lastError.message);
        chrome.test.sendMessage('ready');
      });
    });
  }
});


text:
<?php

namespace Work\MainSiteBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * MemberData
 *
 * @ORM\Table(name="member_data")
 * @ORM\Entity(repositoryClass="Work\MainSiteBundle\Entity\MemberDataRepository")
 */
class MemberData
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     *
     * @ORM\OneToOne(targetEntity="Work\MainSiteBundle\Entity\User")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    private $user;

    /**
     * @ORM\Column(type="string", length=100, name="first_name", nullable=false)
     */
    private $firstName;

    /**
     * @ORM\Column(type="string", length=100, name="last_name", nullable=false)
     */
    private $lastName;

    /**
     * @ORM\Column(type="date", nullable=false)
     */
    private $dob;

    /**
     * @ORM\Column(type="string", length=200, nullable=true)
     */
    private $street;

    /**
     * @ORM\Column(type="string", length=30, nullable=true)
     */
    private $city;

    /**
     * @ORM\Column(type="string", length=30, nullable=true)
     */
    private $state;

    /**
     * @ORM\Column(type="string", length=20, nullable=false)
     */
    private $country;

    /**
     * @ORM\Column(type="string", length=20, nullable=true)
     */
    private $zip;

    /**
     * @ORM\Column(type="string", length=700, nullable=true)
     */
    private $picture;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set user
     *
     * @param \Work\MainSiteBundle\Entity\User $user
     * @return MemberData
     */
    public function setUser(\Work\MainSiteBundle\Entity\User $user = null)
    {
        $this->user = $user;

        return $this;
    }

    /**
     * Get user
     *
     * @return \Work\MainSiteBundle\Entity\User
     */
    public function getUser()
    {
        return $this->user;
    }

    /**
     * Set firstName
     *
     * @param string $firstName
     * @return MemberData
     */
    public function setFirstName($firstName)
    {
        $this->firstName = $firstName;

        return $this;
    }

    /**
     * Get firstName
     *
     * @return string
     */
    public function getFirstName()
    {
        return $this->firstName;
    }

    /**
     * Set lastName
     *
     * @param string $lastName
     * @return MemberData
     */
    public function setLastName($lastName)
    {
        $this->lastName = $lastName;

        return $this;
    }

    /**
     * Get lastName
     *
     * @return string
     */
    public function getLastName()
    {
        return $this->lastName;
    }

    /**
     * Set dob
     *
     * @param \DateTime $dob
     * @return MemberData
     */
    public function setDob($dob)
    {
        $this->dob = $dob;

        return $this;
    }

    /**
     * Get dob
     *
     * @return \DateTime
     */
    public function getDob()
    {
        return $this->dob;
    }

    /**
     * Set street
     *
     * @param string $street
     * @return MemberData
     */
    public function setStreet($street)
    {
        $this->street = $street;

        return $this;
    }

    /**
     * Get street
     *
     * @return string
     */
    public function getStreet()
    {
        return $this->street;
    }

    /**
     * Set city
     *
     * @param string $city
     * @return MemberData
     */
    public function setCity($city)
    {
        $this->city = $city;

        return $this;
    }

    /**
     * Get city
     *
     * @return string
     */
    public function getCity()
    {
        return $this->city;
    }

    /**
     * Set state
     *
     * @param string $state
     * @return MemberData
     */
    public function setState($state)
    {
        $this->state = $state;

        return $this;
    }

    /**
     * Get state
     *
     * @return string
     */
    public function getState()
    {
        return $this->state;
    }

    /**
     * Set country
     *
     * @param string $country
     * @return MemberData
     */
    public function setCountry($country)
    {
        $this->country = $country;

        return $this;
    }

    /**
     * Get country
     *
     * @return string
     */
    public function getCountry()
    {
        return $this->country;
    }

    /**
     * Set zip
     *
     * @param string $zip
     * @return MemberData
     */
    public function setZip($zip)
    {
        $this->zip = $zip;

        return $this;
    }

    /**
     * Get zip
     *
     * @return string
     */
    public function getZip()
    {
        return $this->zip;
    }

    /**
     * Set picture
     *
     * @param string $picture
     * @return MemberData
     */
    public function setPicture($picture)
    {
        $this->picture = $picture;

        return $this;
    }

    /**
     * Get picture
     *
     * @return string
     */
    public function getPicture()
    {
        return $this->picture;
    }
}


text:
package org.springframework.http.client;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Map;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.util.FileCopyUtils;

/**
 * {@link ClientHttpRequest} implementation that uses standard J2SE facilities to execute buffered requests. Created via
 * the {@link SimpleClientHttpRequestFactory}.
 *
 * @author Arjen Poutsma
 * @since 1.0
 * @see SimpleClientHttpRequestFactory#createRequest(java.net.URI, HttpMethod)
 */
final class SimpleBufferingClientHttpRequest extends AbstractBufferingClientHttpRequest {

	private final HttpURLConnection connection;

	SimpleBufferingClientHttpRequest(HttpURLConnection connection) {
		this.connection = connection;
	}

	public HttpMethod getMethod() {
		return HttpMethod.valueOf(this.connection.getRequestMethod());
	}

	public URI getURI() {
		try {
			return this.connection.getURL().toURI();
		} catch (URISyntaxException ex) {
			throw new IllegalStateException("Could not get HttpURLConnection URI: " + ex.getMessage(), ex);
		}
	}

	@Override
	protected ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput) throws IOException {
		for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
			String headerName = entry.getKey();
			for (String headerValue : entry.getValue()) {
				this.connection.addRequestProperty(headerName, headerValue);
			}
		}

		if (this.connection.getDoOutput()) {
			this.connection.setFixedLengthStreamingMode(bufferedOutput.length);
		}
		this.connection.connect();
		if (this.connection.getDoOutput()) {
			FileCopyUtils.copy(bufferedOutput, this.connection.getOutputStream());
		}

		return new SimpleClientHttpResponse(this.connection);
	}

}


text:
package org.terasology.logic.characters;

import groovy.util.ConfigObject;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import org.terasology.game.Terasology;
import org.terasology.logic.audio.Sound;
import org.terasology.logic.manager.*;
import org.terasology.logic.tools.ITool;
import org.terasology.logic.world.Chunk;
import org.terasology.logic.world.IBlockObserver;
import org.terasology.model.blocks.Block;
import org.terasology.model.blocks.BlockGroup;
import org.terasology.model.blocks.management.BlockManager;
import org.terasology.model.inventory.*;
import org.terasology.model.structures.AABB;
import org.terasology.model.structures.BlockPosition;
import org.terasology.model.structures.RayBlockIntersection;
import org.terasology.performanceMonitor.PerformanceMonitor;
import org.terasology.rendering.cameras.Camera;
import org.terasology.rendering.cameras.DefaultCamera;
import org.terasology.rendering.primitives.Mesh;
import org.terasology.rendering.primitives.Tessellator;
import org.terasology.rendering.primitives.TessellatorHelper;
import org.terasology.rendering.world.WorldRenderer;

import javax.vecmath.Vector2f;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector4f;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;

import static org.lwjgl.opengl.GL11.*;

/**
 * Extends the character class and provides support for player functionality. Also provides the
 * modelview matrix from the player's point of view.
 *
 * @author Benjamin Glatzel <benjamin.glatzel@me.com>
 */
public class Player extends Character {

    /* CONSTANT VALUES */
    private static final double MOUSE_SENS = Config.getInstance().getMouseSens();
    private static final boolean DEMO_FLIGHT = Config.getInstance().isDemoFlight();
    private static final double DEMO_FLIGHT_SPEED = Config.getInstance().getDemoFlightSpeed();
    private static final boolean GOD_MODE = Config.getInstance().isGodMode();
    private static final boolean CAMERA_BOBBING = Config.getInstance().isCameraBobbing();

    private static final boolean RENDER_FIRST_PERSON_VIEW = Config.getInstance().isRenderFirstPersonView();
    private static final boolean SHOW_PLACING_BOX = Config.getInstance().isPlacingBox();

    /* OBSERVERS */
    private final ArrayList<IBlockObserver> _observers = new ArrayList<IBlockObserver>();

    /* CAMERA */
    private final DefaultCamera _defaultCamera = new DefaultCamera();
    private final Camera _activeCamera = _defaultCamera;

    /* RENDERING*/
    private boolean _renderPlayerModel;

    /* INTERACTIONS */
    private long _lastInteraction;
    private byte _extractionCounter;
    private RayBlockIntersection.Intersection _selectedBlock, _extractedBlock;
    private float _handMovementAnimationOffset;
    private Mesh _handMesh, _overlayMesh;

    /* INVENTORY */
    private Inventory _inventory = new Inventory();

    /* GOD MODE */
    private long _lastTimeSpacePressed;

    /* RESPAWNING */
    private long _timeOfDeath = -1;

    /* TOOLS */
    private final ToolManager _toolManager = new ToolManager(this);

    public Player(WorldRenderer parent) {
        super(parent);

        // Set the default value for the god mode
        _godMode = GOD_MODE;

        load();
        loadDefaultItems();
    }

    private void loadDefaultItems() {
        _inventory.addItem(new ItemBlock(BlockManager.getInstance().getBlockGroup("Companion")), 1);
        _inventory.addItem(new ItemBlock(BlockManager.getInstance().getBlockGroup("Torch")), 16);
        _inventory.addItem(new ItemPickAxe(), 1);
        _inventory.addItem(new ItemAxe(), 1);
        _inventory.addItem(new ItemBlueprint(), 1);
        _inventory.addItem(new ItemDynamite(), 1);
        _inventory.addItem(new ItemDebug(), 1);
        _inventory.addItem(new ItemRailgun(), 1);
    }

    public void render() {
        super.render();
        updateCameraParameters();

        // Display the block the player is aiming at
        if (SHOW_PLACING_BOX) {
            if (_selectedBlock != null) {
                Block block = BlockManager.getInstance().getBlock(_parent.getWorldProvider().getBlockAtPosition(_selectedBlock.getBlockPosition().toVector3d()));
                if (block.isRenderBoundingBox()) {
                    block.getBounds(_selectedBlock.getBlockPosition()).render(2f);
                }
            }
        }

        // TODO: Replace with a real player model
        if (isRenderPlayerModel())
            getAABB().render(1f);
    }

    public void update(double delta) {
        PerformanceMonitor.startActivity("Player Camera");
        if (_activeCamera != null) {
            _activeCamera.update(delta);

            // Slightly adjust the field of view when flying
            if (_godMode) {
                _activeCamera.extendFov(24);
            } else {
                _activeCamera.resetFov();
            }
        }
        PerformanceMonitor.endActivity();

        if (_handMovementAnimationOffset > 0) {
            _handMovementAnimationOffset -= 0.04;
        } else if (_handMovementAnimationOffset < 0) {
            _handMovementAnimationOffset = 0;
        }

        super.update(delta);

        PerformanceMonitor.startActivity("Player Select Block");
        _selectedBlock = calcSelectedBlock();
        PerformanceMonitor.endActivity();

        PerformanceMonitor.startActivity("Player Death Check");

        // Respawn the player after a certain amount of time
        if (isDead() && _timeOfDeath == -1) {
            _timeOfDeath = Terasology.getInstance().getTimeInMs();
            reset();
        } else if (isDead() && Terasology.getInstance().getTimeInMs() - _timeOfDeath > 1000) {
            revive();
            respawn();
            _timeOfDeath = -1;
        }
        PerformanceMonitor.endActivity();
    }

    /**
     * Processes interactions for the given mouse button.
     *
     * @param button The pressed mouse button
     */
    private void processInteractions(int button) {
        // Throttle interactions
        if (Terasology.getInstance().getTimeInMs() - _lastInteraction < 200) {
            return;
        }

        ITool activeTool = getActiveTool();

        if (activeTool != null) {
            // Check if one of the mouse buttons is pressed
            if (Mouse.isButtonDown(0) || button == 0) {
                activeTool.executeLeftClickAction();
                _lastInteraction = Terasology.getInstance().getTimeInMs();
                poke();
            } else if (Mouse.isButtonDown(1) || button == 1) {
                activeTool.executeRightClickAction();
                _lastInteraction = Terasology.getInstance().getTimeInMs();
                poke();
            }
        }
    }

    public void resetExtraction() {
        _extractedBlock = _selectedBlock;
        _extractionCounter = 0;
    }

    public void poke() {
        _handMovementAnimationOffset = 0.5f;
    }

    public void renderFirstPersonViewElements() {
        if (!RENDER_FIRST_PERSON_VIEW) {
            return;
        }

        glPushMatrix();
        glLoadIdentity();
        glClear(GL_DEPTH_BUFFER_BIT);
        getActiveCamera().loadProjectionMatrix(75f);

        if (getActiveItem() != null) {
            getActiveItem().renderFirstPersonView(this);
        } else {
            renderHand();
        }

        glPopMatrix();
    }

    /**
     * Calculates the bobbing offset factor using sine/cosine functions. The offset adjusted linearly to
     * the player's movement speed.
     *
     * @param phaseOffset Phase offset
     * @param amplitude   Amplitude
     * @param frequency   Frequency
     * @return The bobbing offset
     */
    public double calcBobbingOffset(float phaseOffset, float amplitude, float frequency) {
        if (_godMode || DEMO_FLIGHT)
            return 0;

        return java.lang.Math.sin(_stepCounter * frequency + phaseOffset) * amplitude;
    }

    public void updateCameraParameters() {
        // The camera position is the player's position plus the eye offset
        Vector3d cameraPosition = new Vector3d();
        cameraPosition.add(getPosition(), calcEyeOffset());

        _defaultCamera.getPosition().set(cameraPosition);

        if (CAMERA_BOBBING) {
            _defaultCamera.setBobbingRotationOffsetFactor(calcBobbingOffset(0.0f, 0.01f, 2.5f));
            _defaultCamera.setBobbingVerticalOffsetFactor(calcBobbingOffset((float) java.lang.Math.PI / 4f, 0.025f, 3.0f));
        } else {
            _defaultCamera.setBobbingRotationOffsetFactor(0.0);
            _defaultCamera.setBobbingVerticalOffsetFactor(0.0);
        }

        if (!(DEMO_FLIGHT)) {
            _defaultCamera.getViewingDirection().set(getViewingDirection());
        } else {
            Vector3d viewingTarget = new Vector3d(getPosition().x, 40, getPosition().z - 128);
            _defaultCamera.getViewingDirection().sub(viewingTarget, getPosition());
        }
    }

    public void updatePosition(double delta) {
        // DEMO MODE
        if (DEMO_FLIGHT) {
            getPosition().z -= DEMO_FLIGHT_SPEED;

            int maxHeight = _parent.maxHeightAt((int) getPosition().x, (int) getPosition().z + 8) + 16;

            getPosition().y += (maxHeight - getPosition().y) / 64f;

            if (getPosition().y > 128)
                getPosition().y = 128;

            if (getPosition().y < 40f)
                getPosition().y = 40f;

            return;
        }

        super.updatePosition(delta);
    }

    /**
     * Calculates the currently targeted block in front of the player.
     *
     * @return Intersection point of the targeted block
     */
    public RayBlockIntersection.Intersection calcSelectedBlock() {
        ArrayList<RayBlockIntersection.Intersection> inters = new ArrayList<RayBlockIntersection.Intersection>();

        int blockPosX, blockPosY, blockPosZ;

        for (int x = -3; x <= 3; x++) {
            for (int y = -3; y <= 3; y++) {
                for (int z = -3; z <= 3; z++) {
                    // Make sure the correct block positions are calculated relatively to the position of the player
                    blockPosX = (int) (getPosition().x + (getPosition().x >= 0 ? 0.5f : -0.5f)) + x;
                    blockPosY = (int) (getPosition().y + (getPosition().y >= 0 ? 0.5f : -0.5f)) + y;
                    blockPosZ = (int) (getPosition().z + (getPosition().z >= 0 ? 0.5f : -0.5f)) + z;

                    PerformanceMonitor.startActivity("Player Get Block");
                    byte blockType = _parent.getWorldProvider().getBlock(blockPosX, blockPosY, blockPosZ);
                    PerformanceMonitor.endActivity();

                    // Ignore special blocks
                    if (BlockManager.getInstance().getBlock(blockType).isSelectionRayThrough()) {
                        continue;
                    }

                    // The ray originates from the "player's eye"
                    PerformanceMonitor.startActivity("Player Intersect Block");
                    ArrayList<RayBlockIntersection.Intersection> iss = RayBlockIntersection.executeIntersection(_parent.getWorldProvider(), blockPosX, blockPosY, blockPosZ, calcEyePosition(), _viewingDirection);

                    if (iss != null) {
                        inters.addAll(iss);
                    }
                    PerformanceMonitor.endActivity();
                }
            }
        }

        /**
         * Calculated the closest intersection.
         */
        PerformanceMonitor.startActivity("Player sort intersects");
        if (inters.size() > 0) {
            Collections.sort(inters);
            return inters.get(0);
        }
        PerformanceMonitor.endActivity();

        return null;
    }

    /**
     * Processes the keyboard input.
     *
     * @param key         Pressed key on the keyboard
     * @param state       The state of the key
     * @param repeatEvent True if repeat event
     */
    public void processKeyboardInput(int key, boolean state, boolean repeatEvent) {
        switch (key) {
            case Keyboard.KEY_K:
                if (!repeatEvent && state) {
                    damage(9999);
                }
                break;
            case Keyboard.KEY_SPACE:
                if (!repeatEvent && state) {
                    jump();

                    if (Terasology.getInstance().getTimeInMs() - _lastTimeSpacePressed < 200) {
                        _godMode = !_godMode;
                    }

                    _lastTimeSpacePressed = Terasology.getInstance().getTimeInMs();
                }
                break;
            case Keyboard.KEY_1:
                _inventory.setSelctedCubbyhole(0);
                break;
            case Keyboard.KEY_2:
                _inventory.setSelctedCubbyhole(1);
                break;
            case Keyboard.KEY_3:
                _inventory.setSelctedCubbyhole(2);
                break;
            case Keyboard.KEY_4:
                _inventory.setSelctedCubbyhole(3);
                break;
            case Keyboard.KEY_5:
                _inventory.setSelctedCubbyhole(4);
                break;
            case Keyboard.KEY_6:
                _inventory.setSelctedCubbyhole(5);
                break;
            case Keyboard.KEY_7:
                _inventory.setSelctedCubbyhole(6);
                break;
            case Keyboard.KEY_8:
                _inventory.setSelctedCubbyhole(7);
                break;
            case Keyboard.KEY_9:
                _inventory.setSelctedCubbyhole(8);
                break;
        }
    }

    /**
     * Processes the mouse input.
     *
     * @param button     Pressed mouse button
     * @param state      State of the mouse button
     * @param wheelMoved Distance the mouse wheel moved since last
     */
    public void processMouseInput(int button, boolean state, int wheelMoved) {
        if (isDead())
            return;

        if (wheelMoved != 0) {
            rollSelectedCubby((byte) (wheelMoved / 120));
        } else if (state && (button == 0 || button == 1)) {
            processInteractions(button);
        }
    }

    private void rollSelectedCubby(byte wheelMotion) {
        int selectedCubby = (_inventory.getSelectedCubbyhole() + wheelMotion) % 9;

        if (selectedCubby < 0) {
            selectedCubby = 9 + selectedCubby;
        }

        _inventory.setSelctedCubbyhole(selectedCubby);
    }

    public void updateInput() {
        if (isDead())
            return;

        // Process interactions even if the mouse button is pressed down
        // and not fired by a repeated event
        processInteractions(-1);

        _movementDirection.set(0, 0, 0);

        double dx = Mouse.getDX();
        double dy = Mouse.getDY();

        yaw(dx * MOUSE_SENS);
        pitch(dy * MOUSE_SENS);

        if (Keyboard.isKeyDown(Keyboard.KEY_W)) {
            walkForward();
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_S)) {
            walkBackwards();
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
            strafeLeft();
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
            strafeRight();
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)) {
            moveUp();
        }

        _running = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) && (_touchingGround || _godMode);
    }

    /**
     * Renders the actively selected block in the front of the player's first person perspective.
     */
    public void renderExtractionOverlay() {
        if (_extractionCounter <= 0 || _extractedBlock == null)
            return;

        Block block = BlockManager.getInstance().getBlock(_parent.getWorldProvider().getBlockAtPosition(_extractedBlock.getBlockPosition().toVector3d()));

        ShaderManager.getInstance().enableDefaultTextured();
        TextureManager.getInstance().bindTexture("effects");

        glEnable(GL11.GL_BLEND);
        glBlendFunc(GL_DST_COLOR, GL_ZERO);

        Vector3d cameraPosition = Terasology.getInstance().getActiveCamera().getPosition();

        glPushMatrix();
        glTranslated(_extractedBlock.getBlockPosition().x - cameraPosition.x, _extractedBlock.getBlockPosition().y - cameraPosition.y, _extractedBlock.getBlockPosition().z - cameraPosition.z);

        float offset = java.lang.Math.round(((float) _extractionCounter / block.getHardness()) * 10.0f) * 0.0625f;

        if (_overlayMesh == null) {
            Vector2f texPos = new Vector2f(0.0f, 0.0f);
            Vector2f texWidth = new Vector2f(0.0624f, 0.0624f);

            Tessellator tessellator = new Tessellator();
            TessellatorHelper.addBlockMesh(tessellator, new Vector4f(1, 1, 1, 1), texPos, texWidth, 1.001f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
            _overlayMesh = tessellator.generateMesh();
        }

        glMatrixMode(GL_TEXTURE);
        glPushMatrix();
        glTranslatef(offset, 0f, 0f);
        glMatrixMode(GL_MODELVIEW);

        _overlayMesh.render();

        glPopMatrix();

        glMatrixMode(GL_TEXTURE);
        glPopMatrix();
        glMatrixMode(GL_MODELVIEW);

        glDisable(GL11.GL_BLEND);
    }

    /**
     * Renders a simple hand displayed in front of the player's first person perspective.
     */
    public void renderHand() {
        ShaderManager.getInstance().enableShader("block");
        TextureManager.getInstance().bindTexture("char");

        glPushMatrix();
        glTranslatef(0.8f, -1.1f + (float) calcBobbingOffset((float) java.lang.Math.PI / 8f, 0.05f, 2.5f) - _handMovementAnimationOffset * 0.5f, -1.0f - _handMovementAnimationOffset * 0.5f);
        glRotatef(-45f - _handMovementAnimationOffset * 64.0f, 1.0f, 0.0f, 0.0f);
        glRotatef(35f, 0.0f, 1.0f, 0.0f);
        glTranslatef(0f, 0.25f, 0f);
        glScalef(0.3f, 0.6f, 0.3f);

        if (_handMesh == null) {
            Vector2f texPos = new Vector2f(40.0f * 0.015625f, 32.0f * 0.03125f);
            Vector2f texWidth = new Vector2f(4.0f * 0.015625f, -12.0f * 0.03125f);

            Tessellator tessellator = new Tessellator();
            TessellatorHelper.addBlockMesh(tessellator, new Vector4f(1, 1, 1, 1), texPos, texWidth, 1.0f, 1.0f, 0.9f, 0.0f, 0.0f, 0.0f);
            _handMesh = tessellator.generateMesh();
        }

        _handMesh.render();

        glPopMatrix();
    }

    @SuppressWarnings("unchecked")
    @Override
    public void writePropertiesToConfigObject(ConfigObject co) {
        co.put("playerPositionX", getPosition().x);
        co.put("playerPositionY", getPosition().y);
        co.put("playerPositionZ", getPosition().z);
        co.put("godMode", _godMode);
    }

    @Override
    public void readPropertiesFromConfigObject(ConfigObject co) {
        getPosition().x = ((BigDecimal) co.get("playerPositionX")).doubleValue();
        getPosition().y = ((BigDecimal) co.get("playerPositionY")).doubleValue();
        getPosition().z = ((BigDecimal) co.get("playerPositionZ")).doubleValue();
        _godMode = (Boolean) co.get("godMode");
    }

    @Override
    public String getObjectSavePath() {
        return Terasology.getInstance().getWorldSavePath(_parent.getWorldProvider().getTitle());
    }

    @Override
    public String getObjectFileName() {
        return "PlayerManifest.groovy";
    }

    @Override
    public void dispose() {
        super.dispose();
    }

    public Item getActiveItem() {
        return _inventory.getSelectedItem();
    }

    public BlockGroup getActiveBlock() {
        Item item = getActiveItem();

        if (item != null) {
            if (item.getClass() == ItemBlock.class) {
                return ((ItemBlock) getActiveItem()).getBlockGroup();
            }
        }

        return null;
    }

    public ITool getActiveTool() {
        if (getActiveItem() != null) {
            return _toolManager.getToolForIndex(getActiveItem().getToolId());
        }

        return _toolManager.getToolForIndex((byte) 0x01);
    }

    @Override
    public String toString() {
        return String.format("player (x: %.2f, y: %.2f, z: %.2f | x: %.2f, y: %.2f, z: %.2f | velEarth: %.2f | x: %.2f, y: %.2f, z: %.2f)", getPosition().x, getPosition().y, getPosition().z, _viewingDirection.x, _viewingDirection.y, _viewingDirection.z, _earthVelocity, _movementDirection.x, _movementDirection.y, _movementDirection.z);
    }

    protected AABB generateAABBForPosition(Vector3d p) {
        return new AABB(p, new Vector3d(.3f, 0.8f, .3f));
    }

    public AABB getAABB() {
        return generateAABBForPosition(getPosition());
    }

    public Camera getActiveCamera() {
        return _activeCamera;
    }

    public void registerObserver(IBlockObserver observer) {
        _observers.add(observer);
    }

    public void unregisterObserver(IBlockObserver observer) {
        _observers.remove(observer);
    }

    public void notifyObserversBlockPlaced(Chunk chunk, BlockPosition pos, boolean update) {
        for (IBlockObserver ob : _observers)
            ob.blockPlaced(chunk, pos, update);
    }

    public void notifyObserversBlockRemoved(Chunk chunk, BlockPosition pos, boolean update) {
        for (IBlockObserver ob : _observers)
            ob.blockRemoved(chunk, pos, update);
    }

    public Inventory getInventory() {
        return _inventory;
    }

    public RayBlockIntersection.Intersection getSelectedBlock() {
        return _selectedBlock;
    }

    public RayBlockIntersection.Intersection getExtractedBlock() {
        return _extractedBlock;
    }

    public void setExtractedBlock(RayBlockIntersection.Intersection block) {
        _extractedBlock = block;
    }

    public void setExtractionCounter(byte counter) {
        _extractionCounter = counter;
    }

    public byte getExtractionCounter() {
        return _extractionCounter;
    }

    public float getHandMovementAnimationOffset() {
        return _handMovementAnimationOffset;
    }

    public boolean isCarryingTorch() {
        if (getActiveBlock() != null) {
            if (getActiveBlock().getArchetypeBlock().getLuminance() > 0)
                return true;
        }

        return false;
    }

    @Override
    protected void playFootstep(Sound footStep) {
        AudioManager.play(footStep, this, 0.6f, AudioManager.PRIORITY_HIGH);
    }

    public void setRenderPlayerModel(boolean render) {
        _renderPlayerModel = render;
    }

    public boolean isRenderPlayerModel() {
        return _renderPlayerModel;
    }
}


text:
<?php

/**
 * fzTaggable, is a clone of Doctrine_Template_DmTaggable template class from dmTagPlugin
 *
 * @author fizyk
 */
class fzTaggable extends Doctrine_Template
{

    protected $_options = array(
        'tagClass' => 'fzTag',
        'tagAlias' => 'Tags',
        'className' => '%CLASS%FzTag',
        'generateFiles' => false,
        'table' => false,
        'pluginTable' => false,
        'children' => array(),
        'cascadeDelete' => true,
        'appLevelDelete' => false,
        'cascadeUpdate' => false,
        'options' => array(
            'maxshownitems' => false,
            'maxitems' => false
        )
    );

    public function __construct(array $options = array())
    {
        $this->_options = Doctrine_Lib::arrayDeepMerge($this->_options, $options);

        $this->_plugin = new fzTaggableGenerator($this->_options);
    }

    public function setUp()
    {
        $this->_plugin->initialize($this->_table);

        $className = $this->_table->getComponentName();

        Doctrine_Core::getTable($this->_options['tagClass'])->bind(
                array($className.' as '.$className.'s',
                    array('class' => $className,
                        'local' => 'tag_id',
                        'foreign' => 'id',
                        'refClass' => $this->_plugin->getTable()->getOption('name')
                )), Doctrine_Relation::MANY);
    }

    /**
     * Returns number of tags, which model has been tagged with
     * @return integer
     */
    public function getNbTags()
    {
        return $this->getInvoker()->get($this->_options['tagAlias'])->count();
    }

    /**
     * Check's wheter object has any tags
     * @return boolean
     */
    public function hasTags()
    {
        return $this->getNbTags() > 0;
    }

    /**
     * Returns array with tag names
     * @return array
     */
    public function getTagNames()
    {
        $tagNames = array();
        foreach($this->getInvoker()->get($this->_options['tagAlias']) as $tag)
        {
            $tagNames[] = $tag->get('name');
        }

        return $tagNames;
    }

    /**
     * Returns tags in a string
     * @param string $sep
     * @return string
     */
    public function getTagsAsString($sep = ', ')
    {
        return implode($sep, $this->getTagNames());
    }

    /**
     * Sets the tags for the object, uninking all first, and the linking passed again
     * @param mixed $tags
     * @return self
     */
    public function setTags($tags)
    {
        if(empty($tags))
        {
            $tags = array();
        }

        $tagIds = $this->getTagIds($tags);
        // we're getting all connected tag's ids
        $oldIds = $this->getInvoker()->getTags()->getPrimaryKeys();
        $removeIds = array_diff($oldIds, $tagIds);
        $addIds = array_diff($tagIds, $oldIds);
        // Unlinking deleted tags and decreasing their weight afterwards
        if( count($removeIds) > 0 )
        {
            $this->getInvoker()->unlink($this->_options['tagAlias'], $removeIds);
            fzTagTable::getInstance()->decreaseTagsWeight($removeIds);
        }

        // Linking tags and increasing their weight afterwards
        if( count($addIds) > 0 )
        {
            $this->getInvoker()->link($this->_options['tagAlias'], $addIds);
            fzTagTable::getInstance()->increaseTagsWeight($addIds);
        }

        return $this->getInvoker();
    }

    /**
     * adds tags to the object
     * @param mixed $tags
     * @return self
     */
    public function addTags($tags)
    {
        $tagIds = $this->getTagIds($tags);
        $this->getInvoker()->link($this->_options['tagAlias'], $tagIds);
        fzTagTable::getInstance()->increaseTagsWeight($tagIds);

        return $this->getInvoker();
    }

    /**
     * Removes tags from the object
     * @param mixed $tags
     * @return self
     */
    public function removeTags($tags)
    {
        $tagIds = $this->getTagIds($tags);
        $this->getInvoker()->unlink($this->_options['tagAlias'], $tagIds);
        fzTagTable::getInstance()->decreaseTagsWeight($tagIds);

        return $this->getInvoker();
    }

    /**
     * Removes all tags from the tagged object
     * @return self
     */
    public function removeAllTags()
    {
        $tagIds = $this->getInvoker()->getTags()->getPrimaryKeys();
        $this->getInvoker()->unlink($this->_options['tagAlias']);
        fzTagTable::getInstance()->decreaseTagsWeight($tagIds);

        return $this->getInvoker();
    }

    /**
     * returns related records of the same type
     * @param integer $hydrationMode
     * @return mixed
     */
    public function getRelatedRecords($hydrationMode = Doctrine::HYDRATE_RECORD)
    {
        return $this->getRelatedRecordsQuery()
                ->execute(array(), $hydrationMode);
    }

    /**
     * Checks wheter object has tag related objects
     * @return integer
     */
    public function hasRelatedRecords()
    {
        return $this->getRelatedRecordsQuery()
                ->count();
    }

    /**
     * Returns doctrine query
     * @return Doctrine_Query
     */
    public function getRelatedRecordsQuery()
    {
        return $this->getInvoker()->getTable()
                ->createQuery('a')
                ->leftJoin('a.Tags t')
                ->whereIn('t.id', $this->getCurrentTagIds())
                ->andWhere('a.id != ?', $this->getInvoker()->get('id'));
    }

    /**
     * Returns ids of tags, the object is tagged with
     * @return array
     */
    public function getCurrentTagIds()
    {
        $tagIds = array();
        foreach($this->getInvoker()->get($this->_options['tagAlias']) as $tag)
        {
            $tagIds[] = $tag->get('id');
        }

        return $tagIds;
    }

    /**
     * Returns tags id's
     * @param mixed $tags
     * @return mixed
     */
    private function getTagIds($tags)
    {
        if(is_string($tags))
        {
            //Get array from stringed tags
            $tagNames = array_unique(array_filter(array_map('trim', explode(',', $tags))));

            $tagsList = array();
            if(!empty($tagNames))
            {
                //Get tag table
                $tagTable = Doctrine_Core::getTable($this->_options['tagClass']);

                foreach($tagNames as $tagName)
                {
                    //check if tag is existing in db
                    $_existingTag = $tagTable
                                    ->createQuery('t')
                                    ->select('t.id')
                                    ->where('t.name = ?', $tagName)
                                    ->limit(1)->fetchOne(array(), Doctrine_Core::HYDRATE_ARRAY);
                    //if tag is not in db, insert tag
                    if(empty($_existingTag))
                    {
                        $tag = new $this->_options['tagClass']();
                        $tag->set('name', $tagName);
                        $tag->save();
                        $tagsList[] = $tag->get('id');
                    }
                    //If it is, add it's id to the array
                    else
                    {
                        $tagsList[] = $_existingTag['id'];
                    }
                }
            }

            return $tagsList;
        }
        elseif(is_array($tags))
        {
            if(is_numeric(current($tags)))
            {
                return $tags;
            }
            else
            {
                return $this->getTagIds(implode(',', $tags));
            }
        }
        elseif($tags instanceof Doctrine_Collection)
        {
            return $tags->getPrimaryKeys();
        }
        else
        {
            throw new Doctrine_Exception('Invalid $tags data provided. Must be a string of tags, an array of tag ids, or a Doctrine_Collection of tag records.');
        }
    }

}

?>


text:
import Mixin from '../../types/mixin';

/**
 * This mixin allows for Ember objects to subscribe to and emit events.
 */
interface Evented {
  /**
   * Subscribes to a named event with given function.
   */
  on<Target>(
    name: string,
    target: Target,
    method: string | ((this: Target, ...args: any[]) => void)
  ): this;
  on(name: string, method: ((...args: any[]) => void) | string): this;
  /**
   * Subscribes a function to a named event and then cancels the subscription
   * after the first time the event is triggered. It is good to use ``one`` when
   * you only care about the first time an event has taken place.
   */
  one<Target>(
    name: string,
    target: Target,
    method: string | ((this: Target, ...args: any[]) => void)
  ): this;
  one(name: string, method: string | ((...args: any[]) => void)): this;
  /**
   * Triggers a named event for the object. Any additional arguments
   * will be passed as parameters to the functions that are subscribed to the
   * event.
   */
  trigger(name: string, ...args: any[]): any;
  /**
   * Cancels subscription for given name, target, and method.
   */
  off<Target>(
    name: string,
    target: Target,
    method: string | ((this: Target, ...args: any[]) => void)
  ): this;
  off(name: string, method: string | ((...args: any[]) => void)): this;
  /**
   * Checks to see if object has any subscriptions for named event.
   */
  has(name: string): boolean;
}

declare const Evented: Mixin;
export default Evented;