Context:
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.com
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <stdio.h>
#include "LinearMath/btIDebugDraw.h"
#include "BulletCollision/CollisionDispatch/btGhostObject.h"
#include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
#include "LinearMath/btDefaultMotionState.h"
#include "btKinematicCharacterController.h"
// static helper method
static btVector3
getNormalizedVector(ref btVector3 v)
{
	btVector3 n(0, 0, 0);
	if (v.length() > SIMD_EPSILON) {
		n = v.normalized();
	}
	return n;
}
///@todo Interact with dynamic objects,
///Ride kinematicly animated platforms properly
///More realistic (or maybe just a config option) falling
/// . Should integrate falling velocity manually and use that in stepDown()
///Support jumping
///Support ducking
class btKinematicClosestNotMeRayResultCallback : btCollisionWorld::ClosestRayResultCallback
{
public:
	btKinematicClosestNotMeRayResultCallback (btCollisionObject me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0))
	{
		m_me = me;
	}
	virtual double addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
	{
		if (rayResult.m_collisionObject == m_me)
			return 1.0;
		return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace);
	}
protected:
	btCollisionObject m_me;
};
class btKinematicClosestNotMeConvexResultCallback : btCollisionWorld::ClosestConvexResultCallback
{
public:
	btKinematicClosestNotMeConvexResultCallback (btCollisionObject me, ref btVector3 up, double minSlopeDot)
	: btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0))
	, m_me(me)
	, m_up(up)
	, m_minSlopeDot(minSlopeDot)
	{
	}
	virtual double addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace)
	{
		if (convexResult.m_hitCollisionObject == m_me)
			return (double)(1.0);
		if (!convexResult.m_hitCollisionObject.hasContactResponse())
			return (double)(1.0);
		btVector3 hitNormalWorld;
		if (normalInWorldSpace)
		{
			hitNormalWorld = convexResult.m_hitNormalLocal;
		} else
		{
			///need to transform normal into worldspace
			hitNormalWorld = convexResult.m_hitCollisionObject.getWorldTransform().getBasis()*convexResult.m_hitNormalLocal;
		}
		double dotUp = m_up.dot(hitNormalWorld);
		if (dotUp < m_minSlopeDot) {
			return (double)(1.0);
		}
		return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace);
	}
protected:
	btCollisionObject m_me;
	btVector3 m_up;
	double m_minSlopeDot;
};
/*
 * Returns the reflection direction of a ray going 'direction' hitting a surface with normal 'normal'
 *
 * from: http://www-cs-students.stanford.edu/~adityagp/final/node3.html
 */
btVector3 btKinematicCharacterController::computeReflectionDirection (ref btVector3 direction, ref btVector3 normal)
{
	return direction - ((double)(2.0) * direction.dot(normal)) * normal;
}
/*
 * Returns the portion of 'direction' that is parallel to 'normal'
 */
btVector3 btKinematicCharacterController::parallelComponent (ref btVector3 direction, ref btVector3 normal)
{
	double magnitude = direction.dot(normal);
	return normal * magnitude;
}
/*
 * Returns the portion of 'direction' that is perpindicular to 'normal'
 */
btVector3 btKinematicCharacterController::perpindicularComponent (ref btVector3 direction, ref btVector3 normal)
{
	return direction - parallelComponent(direction, normal);
}
btKinematicCharacterController::btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,double stepHeight, int upAxis)
{
	m_upAxis = upAxis;
	m_addedMargin = 0.02;
	m_walkDirection.setValue(0,0,0);
	m_useGhostObjectSweepTest = true;
	m_ghostObject = ghostObject;
	m_stepHeight = stepHeight;
	m_turnAngle = (double)(0.0);
	m_convexShape=convexShape;
	m_useWalkDirection = true;	// use walk direction by default, legacy behavior
	m_velocityTimeInterval = 0.0;
	m_verticalVelocity = 0.0;
	m_verticalOffset = 0.0;
	m_gravity = 9.8 * 3 ; // 3G acceleration.
	m_fallSpeed = 55.0; // Terminal velocity of a sky diver in m/s.
	m_jumpSpeed = 10.0; // ?
	m_wasOnGround = false;
	m_wasJumping = false;
	m_interpolateUp = true;
	setMaxSlope(btRadians(45.0));
	m_currentStepOffset = 0;
	full_drop = false;
	bounce_fix = false;
}
btKinematicCharacterController::~btKinematicCharacterController ()
{
}
btPairCachingGhostObject* btKinematicCharacterController::getGhostObject()
{
	return m_ghostObject;
}
bool btKinematicCharacterController::recoverFromPenetration ( btCollisionWorld* collisionWorld)
{
	// Here we must refresh the overlapping paircache as the penetrating movement itself or the
	// previous recovery iteration might have used setWorldTransform and pushed us into an object
	// that is not in the previous cache contents from the last timestep, as will happen if we
	// are pushed into a new AABB overlap. Unhandled this means the next convex sweep gets stuck.
	//
	// Do this by calling the broadphase's setAabb with the moved AABB, this will update the broadphase
	// paircache and the ghostobject's internal paircache at the same time.    /BW
	btVector3 minAabb, maxAabb;
	m_convexShape.getAabb(m_ghostObject.getWorldTransform(), minAabb,maxAabb);
	collisionWorld.getBroadphase().setAabb(m_ghostObject.getBroadphaseHandle(),
						 minAabb,
						 maxAabb,
						 collisionWorld.getDispatcher());

	bool penetration = false;
	collisionWorld.getDispatcher().dispatchAllCollisionPairs(m_ghostObject.getOverlappingPairCache(), collisionWorld.getDispatchInfo(), collisionWorld.getDispatcher());
	m_currentPosition = m_ghostObject.getWorldTransform().getOrigin();

	double maxPen = (double)(0.0);
	for (int i = 0; i < m_ghostObject.getOverlappingPairCache().getNumOverlappingPairs(); i++)
	{
		m_manifoldArray.resize(0);
		btBroadphasePair* collisionPair = &m_ghostObject.getOverlappingPairCache().getOverlappingPairArray()[i];
		btCollisionObject obj0 = static_cast<btCollisionObject>(collisionPair.m_pProxy0.m_clientObject);
                btCollisionObject obj1 = static_cast<btCollisionObject>(collisionPair.m_pProxy1.m_clientObject);
		if ((obj0 && !obj0.hasContactResponse()) || (obj1 && !obj1.hasContactResponse()))
			continue;

		if (collisionPair.m_algorithm)
			collisionPair.m_algorithm.getAllContactManifolds(m_manifoldArray);

		for (int j=0;j<m_manifoldArray.Count;j++)
		{
			btPersistentManifold* manifold = m_manifoldArray[j];
			double directionSign = manifold.getBody0() == m_ghostObject ? (double)(-1.0) : (double)(1.0);
			for (int p=0;p<manifold.getNumContacts();p++)
			{
				btManifoldPointpt = manifold.getContactPoint(p);
				double dist = pt.getDistance();
				if (dist < 0.0)
				{
					if (dist < maxPen)
					{
						maxPen = dist;
						m_touchingNormal = pt.m_normalWorldOnB * directionSign;//??
					}
					m_currentPosition += pt.m_normalWorldOnB * directionSign * dist * (double)(0.2);
					penetration = true;
				} else {
					//Console.WriteLine("touching %f\n", dist);
				}
			}

			//manifold.clearManifold();
		}
	}
	btTransform newTrans = m_ghostObject.getWorldTransform();
	newTrans.setOrigin(m_currentPosition);
	m_ghostObject.setWorldTransform(newTrans);
//	Console.WriteLine("m_touchingNormal = %f,%f,%f\n",m_touchingNormal,m_touchingNormal[1],m_touchingNormal[2]);
	return penetration;
}
void btKinematicCharacterController::stepUp ( btCollisionWorld* world)
{
	// phase 1: up
	btTransform start, end;
	m_targetPosition = m_currentPosition + getUpAxisDirections()[m_upAxis] * (m_stepHeight + (m_verticalOffset > 0?m_verticalOffset:0));
	start.setIdentity ();
	end.setIdentity ();
	/* FIXME: Handle penetration properly */
	start.setOrigin (m_currentPosition + getUpAxisDirections()[m_upAxis] * (m_convexShape.getMargin() + m_addedMargin));
	end.setOrigin (m_targetPosition);
	btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, -getUpAxisDirections()[m_upAxis], (double)(0.7071));
	callback.m_collisionFilterGroup = getGhostObject().getBroadphaseHandle().m_collisionFilterGroup;
	callback.m_collisionFilterMask = getGhostObject().getBroadphaseHandle().m_collisionFilterMask;

	if (m_useGhostObjectSweepTest)
	{
		m_ghostObject.convexSweepTest (m_convexShape, start, end, callback, world.getDispatchInfo().m_allowedCcdPenetration);
	}
	else
	{
		world.convexSweepTest (m_convexShape, start, end, callback);
	}

	if (callback.hasHit())
	{
		// Only modify the position if the hit was a slope and not a wall or ceiling.
		if(callback.m_hitNormalWorld.dot(getUpAxisDirections()[m_upAxis]) > 0.0)
		{
			// we moved up only a fraction of the step height
			m_currentStepOffset = m_stepHeight * callback.m_closestHitFraction;
			if (m_interpolateUp == true)
				m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
			else
				m_currentPosition = m_targetPosition;
		}
		m_verticalVelocity = 0.0;
		m_verticalOffset = 0.0;
	} else {
		m_currentStepOffset = m_stepHeight;
		m_currentPosition = m_targetPosition;
	}
}
void btKinematicCharacterController::updateTargetPositionBasedOnCollision (ref btVector3 hitNormal, double tangentMag, double normalMag)
{
	btVector3 movementDirection = m_targetPosition - m_currentPosition;
	double movementLength = movementDirection.length();
	if (movementLength>SIMD_EPSILON)
	{
		movementDirection.normalize();
		btVector3 reflectDir = computeReflectionDirection (movementDirection, hitNormal);
		reflectDir.normalize();
		btVector3 parallelDir, perpindicularDir;
		parallelDir = parallelComponent (reflectDir, hitNormal);
		perpindicularDir = perpindicularComponent (reflectDir, hitNormal);
		m_targetPosition = m_currentPosition;
		if (0)//tangentMag != 0.0)
		{
			btVector3 parComponent = parallelDir * double (tangentMag*movementLength);
//			Console.WriteLine("parComponent=%f,%f,%f\n",parComponent[0],parComponent[1],parComponent[2]);
			m_targetPosition +=  parComponent;
		}
		if (normalMag != 0.0)
		{
			btVector3 perpComponent = perpindicularDir * double (normalMag*movementLength);
//			Console.WriteLine("perpComponent=%f,%f,%f\n",perpComponent[0],perpComponent[1],perpComponent[2]);
			m_targetPosition += perpComponent;
		}
	} else
	{
//		Console.WriteLine("movementLength don't normalize a zero vector\n");
	}
}
void btKinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* collisionWorld, ref btVector3 walkMove)
{
	// Console.WriteLine("m_normalizedDirection=%f,%f,%f\n",
	// 	m_normalizedDirection[0],m_normalizedDirection[1],m_normalizedDirection[2]);
	// phase 2: forward and strafe
	btTransform start, end;
	m_targetPosition = m_currentPosition + walkMove;
	start.setIdentity ();
	end.setIdentity ();

	double fraction = 1.0;
	double distance2 = (m_currentPosition-m_targetPosition).length2();
//	Console.WriteLine("distance2=%f\n",distance2);
	if (m_touchingContact)
	{
		if (m_normalizedDirection.dot(m_touchingNormal) > (double)(0.0))
		{
			//interferes with step movement
			//updateTargetPositionBasedOnCollision (m_touchingNormal);
		}
	}
	int maxIter = 10;
	while (fraction > (double)(0.01) && maxIter-- > 0)
	{
		start.setOrigin (m_currentPosition);
		end.setOrigin (m_targetPosition);
		btVector3 sweepDirNegative(m_currentPosition - m_targetPosition);
		btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, sweepDirNegative, (double)(0.0));
		callback.m_collisionFilterGroup = getGhostObject().getBroadphaseHandle().m_collisionFilterGroup;
		callback.m_collisionFilterMask = getGhostObject().getBroadphaseHandle().m_collisionFilterMask;
		double margin = m_convexShape.getMargin();
		m_convexShape.setMargin(margin + m_addedMargin);
		if (m_useGhostObjectSweepTest)
		{
			m_ghostObject.convexSweepTest (m_convexShape, start, end, callback, collisionWorld.getDispatchInfo().m_allowedCcdPenetration);
		} else
		{
			collisionWorld.convexSweepTest (m_convexShape, start, end, callback, collisionWorld.getDispatchInfo().m_allowedCcdPenetration);
		}

		m_convexShape.setMargin(margin);

		fraction -= callback.m_closestHitFraction;
		if (callback.hasHit())
		{
			// we moved only a fraction
			//double hitDistance;
			//hitDistance = (callback.m_hitPointWorld - m_currentPosition).length();
//			m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
			updateTargetPositionBasedOnCollision (callback.m_hitNormalWorld);
			btVector3 currentDir = m_targetPosition - m_currentPosition;
			distance2 = currentDir.length2();
			if (distance2 > SIMD_EPSILON)
			{
				currentDir.normalize();
				/* See Quake2: "If velocity is against original velocity, stop ead to avoid tiny oscilations in sloping corners." */
				if (currentDir.dot(m_normalizedDirection) <= (double)(0.0))
				{
					break;
				}
			} else
			{
//				Console.WriteLine("currentDir: don't normalize a zero vector\n");
				break;
			}
		} else {
			// we moved whole way
			m_currentPosition = m_targetPosition;
		}
	//	if (callback.m_closestHitFraction == 0)
	//		break;
	}
}
void btKinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld, double dt)
{
	btTransform start, end, end_double;
	bool runonce = false;
	// phase 3: down
	/*double additionalDownStep = (m_wasOnGround && !onGround()) ? m_stepHeight : 0.0;
	btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + additionalDownStep);
	double downVelocity = (additionalDownStep == 0.0 && m_verticalVelocity<0.0?-m_verticalVelocity:0.0) * dt;
	btVector3 gravity_drop = getUpAxisDirections()[m_upAxis] * downVelocity;
	m_targetPosition -= (step_drop + gravity_drop);*/
	btVector3 orig_position = m_targetPosition;

	double downVelocity = (m_verticalVelocity<0?-m_verticalVelocity:0) * dt;
	if(downVelocity > 0.0 && downVelocity > m_fallSpeed
		&& (m_wasOnGround || !m_wasJumping))
		downVelocity = m_fallSpeed;
	btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
	m_targetPosition -= step_drop;
	btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, getUpAxisDirections()[m_upAxis], m_maxSlopeCosine);
        callback.m_collisionFilterGroup = getGhostObject().getBroadphaseHandle().m_collisionFilterGroup;
        callback.m_collisionFilterMask = getGhostObject().getBroadphaseHandle().m_collisionFilterMask;
        btKinematicClosestNotMeConvexResultCallback callback2 (m_ghostObject, getUpAxisDirections()[m_upAxis], m_maxSlopeCosine);
        callback2.m_collisionFilterGroup = getGhostObject().getBroadphaseHandle().m_collisionFilterGroup;
        callback2.m_collisionFilterMask = getGhostObject().getBroadphaseHandle().m_collisionFilterMask;
	while (1)
	{
		start.setIdentity ();
		end.setIdentity ();
		end_double.setIdentity ();
		start.setOrigin (m_currentPosition);
		end.setOrigin (m_targetPosition);
		//set double test for 2x the step drop, to check for a large drop vs small drop
		end_double.setOrigin (m_targetPosition - step_drop);
		if (m_useGhostObjectSweepTest)
		{
			m_ghostObject.convexSweepTest (m_convexShape, start, end, callback, collisionWorld.getDispatchInfo().m_allowedCcdPenetration);
			if (!callback.hasHit())
			{
				//test a double fall height, to see if the character should interpolate it's fall (full) or not (partial)
				m_ghostObject.convexSweepTest (m_convexShape, start, end_double, callback2, collisionWorld.getDispatchInfo().m_allowedCcdPenetration);
			}
		} else
		{
			collisionWorld.convexSweepTest (m_convexShape, start, end, callback, collisionWorld.getDispatchInfo().m_allowedCcdPenetration);
			if (!callback.hasHit())
					{
							//test a double fall height, to see if the character should interpolate it's fall (large) or not (small)
							collisionWorld.convexSweepTest (m_convexShape, start, end_double, callback2, collisionWorld.getDispatchInfo().m_allowedCcdPenetration);
					}
		}

		double downVelocity2 = (m_verticalVelocity<0?-m_verticalVelocity:0) * dt;
		bool has_hit = false;
		if (bounce_fix == true)
			has_hit = callback.hasHit() || callback2.hasHit();
		else
			has_hit = callback2.hasHit();
		if(downVelocity2 > 0.0 && downVelocity2 < m_stepHeight && has_hit == true && runonce == false
					&& (m_wasOnGround || !m_wasJumping))
		{
			//redo the velocity calculation when falling a small amount, for fast stairs motion
			//for larger falls, use the smoother/slower interpolated movement by not touching the target position
			m_targetPosition = orig_position;
					downVelocity = m_stepHeight;
				btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
			m_targetPosition -= step_drop;
			runonce = true;
			continue; //re-run previous tests
		}
		break;
	}
	if (callback.hasHit() || runonce == true)
	{
		// we dropped a fraction of the height . hit floor
		double fraction = (m_currentPosition.y - callback.m_hitPointWorld.y) / 2;
		//Console.WriteLine("hitpoint: %g - pos %g\n", callback.m_hitPointWorld.y, m_currentPosition.y);
		if (bounce_fix == true)
		{
			if (full_drop == true)
                                m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
                        else
                                //due to errors in the closestHitFraction variable when used with large polygons, calculate the hit fraction manually
                                m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, fraction);
		}
		else
			m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
		full_drop = false;
		m_verticalVelocity = 0.0;
		m_verticalOffset = 0.0;
		m_wasJumping = false;
	} else {
		// we dropped the full height

		full_drop = true;
		if (bounce_fix == true)
		{
			downVelocity = (m_verticalVelocity<0?-m_verticalVelocity:0) * dt;
			if (downVelocity > m_fallSpeed && (m_wasOnGround || !m_wasJumping))
			{
				m_targetPosition += step_drop; //undo previous target change
				downVelocity = m_fallSpeed;
				step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
				m_targetPosition -= step_drop;
			}
		}
		//Console.WriteLine("full drop - %g, %g\n", m_currentPosition.y, m_targetPosition.y);
		m_currentPosition = m_targetPosition;
	}
}
void btKinematicCharacterController::setWalkDirection
(
ref btVector3 walkDirection
)
{
	m_useWalkDirection = true;
	m_walkDirection = walkDirection;
	m_normalizedDirection = getNormalizedVector(m_walkDirection);
}
void btKinematicCharacterController::setVelocityForTimeInterval
(
ref btVector3 velocity,
double timeInterval
)
{
//	Console.WriteLine("setVelocity!\n");
//	Console.WriteLine("  interval: %f\n", timeInterval);
//	Console.WriteLine("  velocity: (%f, %f, %f)\n",
//		 velocity.x, velocity.y, velocity.z);
	m_useWalkDirection = false;
	m_walkDirection = velocity;
	m_normalizedDirection = getNormalizedVector(m_walkDirection);
	m_velocityTimeInterval += timeInterval;
}
void btKinematicCharacterController::reset ( btCollisionWorld* collisionWorld )
{
        m_verticalVelocity = 0.0;
        m_verticalOffset = 0.0;
        m_wasOnGround = false;
        m_wasJumping = false;
        m_walkDirection.setValue(0,0,0);
        m_velocityTimeInterval = 0.0;
        //clear pair cache
        btHashedOverlappingPairCache *cache = m_ghostObject.getOverlappingPairCache();
        while (cache.getOverlappingPairArray().Count > 0)
        {
                cache.removeOverlappingPair(cache.getOverlappingPairArray()[0].m_pProxy0, cache.getOverlappingPairArray()[0].m_pProxy1, collisionWorld.getDispatcher());
        }
}
void btKinematicCharacterController::warp (ref btVector3 origin)
{
	btTransform xform;
	xform.setIdentity();
	xform.setOrigin (origin);
	m_ghostObject.setWorldTransform (xform);
}
void btKinematicCharacterController::preStep (  btCollisionWorld* collisionWorld)
{

	int numPenetrationLoops = 0;
	m_touchingContact = false;
	while (recoverFromPenetration (collisionWorld))
	{
		numPenetrationLoops++;
		m_touchingContact = true;
		if (numPenetrationLoops > 4)
		{
			//Console.WriteLine("character could not recover from penetration = %d\n", numPenetrationLoops);
			break;
		}
	}
	m_currentPosition = m_ghostObject.getWorldTransform().getOrigin();
	m_targetPosition = m_currentPosition;
//	Console.WriteLine("m_targetPosition=%f,%f,%f\n",m_targetPosition[0],m_targetPosition[1],m_targetPosition[2]);

}
#include <stdio.h>
void btKinematicCharacterController::playerStep (  btCollisionWorld* collisionWorld, double dt)
{
//	Console.WriteLine("playerStep(): ");
//	Console.WriteLine("  dt = %f", dt);
	// quick check...
	if (!m_useWalkDirection & (m_velocityTimeInterval <= 0.0 || m_walkDirection.fuzzyZero())) {
//		Console.WriteLine("\n");
		return;		// no motion
	}
	m_wasOnGround = onGround();
	// Update fall velocity.
	m_verticalVelocity -= m_gravity * dt;
	if(m_verticalVelocity > 0.0 && m_verticalVelocity > m_jumpSpeed)
	{
		m_verticalVelocity = m_jumpSpeed;
	}
	if(m_verticalVelocity < 0.0 && btFabs(m_verticalVelocity) > btFabs(m_fallSpeed))
	{
		m_verticalVelocity = -btFabs(m_fallSpeed);
	}
	m_verticalOffset = m_verticalVelocity * dt;
	btTransform xform;
	xform = m_ghostObject.getWorldTransform ();
//	Console.WriteLine("walkDirection(%f,%f,%f)\n",walkDirection,walkDirection[1],walkDirection[2]);
//	Console.WriteLine("walkSpeed=%f\n",walkSpeed);
	stepUp (collisionWorld);
	if (m_useWalkDirection) {
		stepForwardAndStrafe (collisionWorld, m_walkDirection);
	} else {
		//Console.WriteLine("  time: %f", m_velocityTimeInterval);
		// still have some time left for moving!
		double dtMoving =
			(dt < m_velocityTimeInterval) ? dt : m_velocityTimeInterval;
		m_velocityTimeInterval -= dt;
		// how far will we move while we are moving?
		btVector3 move = m_walkDirection * dtMoving;
		//Console.WriteLine("  dtMoving: %f", dtMoving);
		// okay, step
		stepForwardAndStrafe(collisionWorld, move);
	}
	stepDown (collisionWorld, dt);
	// Console.WriteLine("\n");
	xform.setOrigin (m_currentPosition);
	m_ghostObject.setWorldTransform (xform);
}
void btKinematicCharacterController::setFallSpeed (double fallSpeed)
{
	m_fallSpeed = fallSpeed;
}
void btKinematicCharacterController::setJumpSpeed (double jumpSpeed)
{
	m_jumpSpeed = jumpSpeed;
}
void btKinematicCharacterController::setMaxJumpHeight (double maxJumpHeight)
{
	m_maxJumpHeight = maxJumpHeight;
}
bool btKinematicCharacterController::canJump ()
{
	return onGround();
}
void btKinematicCharacterController::jump ()
{
	if (!canJump())
		return;
	m_verticalVelocity = m_jumpSpeed;
	m_wasJumping = true;
#if 0
	currently no jumping.
	btTransform xform;
	m_rigidBody.getMotionState().getWorldTransform (xform);
	btVector3 up = xform.getBasis()[1];
	up.normalize ();
	double magnitude = ((double)(1.0)/m_rigidBody.getInvMass()) * (double)(8.0);
	m_rigidBody.applyCentralImpulse (up * magnitude);
#endif
}
void btKinematicCharacterController::setGravity(double gravity)
{
	m_gravity = gravity;
}
double btKinematicCharacterController::getGravity()
{
	return m_gravity;
}
void btKinematicCharacterController::setMaxSlope(double slopeRadians)
{
	m_maxSlopeRadians = slopeRadians;

Answer: m_maxSlopeCosine = btCos(slopeRadians);


Context:
from django import forms
from django.forms import ValidationError
from django.contrib.auth.models import Group
from common.forms import ModelFormWithHelper
from common.helpers import SubmitCancelFormHelper
from community.constants import COMMUNITY_ADMIN, COMMUNITY_PRESENCE_CHOICES
from community.models import Community, CommunityPage, RequestCommunity
from community.utils import get_groups
from users.models import SystersUser
class AddCommunityForm(ModelFormWithHelper):
    """ Form to create a new Community by admin. """
    class Meta:
        model = Community
        fields = ('name', 'slug', 'order', 'location', 'email', 'mailing_list',
                  'parent_community', 'website', 'facebook', 'googleplus',
                  'twitter')
        helper_class = SubmitCancelFormHelper
        helper_cancel_href = "{% url 'index' %}"
    def __init__(self, *args, **kwargs):
        self.admin = kwargs.pop('admin')
        super(AddCommunityForm, self).__init__(*args, **kwargs)
    def save(self, commit=True):
        """Override save to add admin to the instance"""
        instance = super(AddCommunityForm, self).save(commit=False)
        instance.admin = self.admin
        if commit:
            instance.save()
        return instance
class RequestCommunityForm(ModelFormWithHelper):
    """Form to request a new Community"""
    def __init__(self, *args, **kwargs):
        """Makes some fields required and modifies a field to use widget"""
        self.user = kwargs.pop('user')
        super(RequestCommunityForm, self).__init__(*args, **kwargs)
        self.fields['social_presence'] = forms.MultipleChoiceField(
            choices=COMMUNITY_PRESENCE_CHOICES, label="Check off all \
            the social media accounts you can manage for your proposed community:",
            required=False, widget=forms.CheckboxSelectMultiple)
        self.fields['email'].required = True
        self.fields['demographic_target_count'].required = True
        self.fields['purpose'].required = True
        self.fields['content_developer'].required = True
        self.fields['selection_criteria'].required = True
        self.fields['is_real_time'].required = True
    class Meta:
        model = RequestCommunity
        fields = ('is_member', 'email_id', 'email', 'name', 'slug', 'order', 'location',
                  'type_community', 'other_community_type', 'parent_community',
                  'community_channel', 'mailing_list', 'website', 'facebook',
                  'googleplus', 'twitter', 'social_presence', 'other_account',
                  'demographic_target_count',
                  'purpose', 'is_avail_volunteer', 'count_avail_volunteer', 'content_developer',
                  'selection_criteria', 'is_real_time')
        helper_class = SubmitCancelFormHelper
        helper_cancel_href = "{% url 'index' %}"
    def clean_social_presence(self):
        """Converts the checkbox input into char to save it to the instance's field."""
        social_presence = ', '.join(
            map(str, self.cleaned_data['social_presence']))
        return social_presence
    def save(self, commit=True):
        """Override save to add user to the instance"""
        instance = super(RequestCommunityForm, self).save(commit=False)
        instance.user = SystersUser.objects.get(user=self.user)
        if commit:
            instance.save()
        return instance
class EditCommunityRequestForm(ModelFormWithHelper):
    """Form to edit a community request"""
    def __init__(self, *args, **kwargs):
        """Makes some fields required and modifies a field to use widget"""
        super(EditCommunityRequestForm, self).__init__(*args, **kwargs)
        self.fields['social_presence'] = forms.MultipleChoiceField(
            choices=COMMUNITY_PRESENCE_CHOICES, label="Check off all \
            the social media accounts you can manage for your proposed community:",
            required=False, widget=forms.CheckboxSelectMultiple)
        self.fields['email'].required = True
        self.fields['demographic_target_count'].required = True
        self.fields['purpose'].required = True
        self.fields['content_developer'].required = True
        self.fields['selection_criteria'].required = True
        self.fields['is_real_time'].required = True
    class Meta:
        model = RequestCommunity
        fields = ('is_member', 'email_id', 'email', 'name', 'slug', 'order', 'location',
                  'type_community', 'other_community_type', 'parent_community',
                  'community_channel', 'mailing_list', 'website', 'facebook',
                  'googleplus', 'twitter', 'social_presence', 'other_account',
                  'demographic_target_count',
                  'purpose', 'is_avail_volunteer', 'count_avail_volunteer', 'content_developer',
                  'selection_criteria', 'is_real_time')
        widgets = {'social_presence': forms.CheckboxSelectMultiple}
        helper_class = SubmitCancelFormHelper
        helper_cancel_href = "{% url 'view_community_request' community_request.slug %}"
    def clean_social_presence(self):
        """Converts the checkbox input into char to save it to the instance's field."""
        social_presence = ', '.join(
            map(str, self.cleaned_data['social_presence']))
        return social_presence
    def clean_slug(self):
        """Checks if the slug exists in the Community objects' slug"""
        slug = self.cleaned_data['slug']
        slug_community_values = Community.objects.all().values_list('order', flat=True)
        if slug in slug_community_values:
            msg = "Slug by this value already exists. Please choose a different slug\
                   other than {0}!"
            string_slug_values = ', '.join(map(str, slug_community_values))
            raise ValidationError(msg.format(string_slug_values))
        else:
            return slug
    def clean_order(self):
        """Checks if the order exists in the Community objects' order"""
        order = self.cleaned_data['order']
        order_community_values = list(
            Community.objects.all().values_list('order', flat=True))
        order_community_values.sort()
        if order is None:
            raise ValidationError("Order must not be None.")
        elif order in order_community_values:
            msg = "Choose order value other than {0}"
            string_order_values = ', '.join(map(str, order_community_values))
            raise ValidationError(msg.format(string_order_values))
        else:
            return order
class EditCommunityForm(ModelFormWithHelper):
    """Form to edit Community profile"""
    class Meta:
        model = Community
        fields = ('name', 'slug', 'order', 'location', 'email', 'mailing_list',
                  'parent_community', 'website', 'facebook', 'googleplus',
                  'twitter')
        helper_class = SubmitCancelFormHelper
        helper_cancel_href = "{% url 'view_community_profile' " \
                             "community.slug %}"
class AddCommunityPageForm(ModelFormWithHelper):
    """Form to create new CommunityPage. The author and the community of the
    page are expected to be provided when initializing the form:
    * author - currently logged in user, aka the author of the page
    * community - to which Community the CommunityPage belongs
    """
    class Meta:
        model = CommunityPage
        fields = ('title', 'slug', 'order', 'content')
        helper_class = SubmitCancelFormHelper
        helper_cancel_href = "{% url 'view_community_landing' " \
                             "community.slug %}"
    def __init__(self, *args, **kwargs):
        self.author = kwargs.pop('author')
        self.community = kwargs.pop('community')
        super(AddCommunityPageForm, self).__init__(*args, **kwargs)
    def save(self, commit=True):
        """Override save to add author and community to the instance"""
        instance = super(AddCommunityPageForm, self).save(commit=False)
        instance.author = SystersUser.objects.get(user=self.author)
        instance.community = self.community
        if commit:
            instance.save()
        return instance
class EditCommunityPageForm(ModelFormWithHelper):
    """Form to edit a CommunityPage."""
    class Meta:
        model = CommunityPage
        fields = ('slug', 'title', 'order', 'content')
        helper_class = SubmitCancelFormHelper
        helper_cancel_href = "{% url 'view_community_page' community.slug " \
                             "object.slug %}"
class PermissionGroupsForm(forms.Form):
    """Form to manage (select/deselect) user permission groups"""
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user')
        community = kwargs.pop('community')
        super(PermissionGroupsForm, self).__init__(*args, **kwargs)
        # get all community groups and remove community admin group
        # from the list of choices
        self.groups = list(get_groups(community.name))
        admin_group = Group.objects.get(
            name=COMMUNITY_ADMIN.format(community.name))
        self.groups.remove(admin_group)
        choices = [(group.pk, group.name) for group in self.groups]
        self.fields['groups'] = forms. \
            MultipleChoiceField(choices=choices, label="", required=False,
                                widget=forms.CheckboxSelectMultiple)

Answer: self.member_groups = self.user.get_member_groups(self.groups)


Context:
/*
 * Copyright (C) 2006-2010 - Frictional Games
 *
 * This file is part of HPL1 Engine.
 *
 * HPL1 Engine is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * HPL1 Engine is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with HPL1 Engine.  If not, see <http://www.gnu.org/licenses/>.
 */
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace Mapeditor
{
	/// <summary>
	/// Summary description for PropertiesLightForm.
	/// </summary>
	public class frmPropertiesArea : System.Windows.Forms.Form
	{
		public bool mbOkWasPressed=false;
		cArea mArea;
        private System.Windows.Forms.Label objNameLabel;
		private System.Windows.Forms.Label label1;
		public System.Windows.Forms.Button objOkButton;
		public System.Windows.Forms.Button objCancelButtom;
		public System.Windows.Forms.TextBox objNameText;
		private System.Windows.Forms.Label label6;
		public System.Windows.Forms.ComboBox objActiveBox;
		public System.Windows.Forms.TextBox objXText;
		private System.Windows.Forms.Label objXLabel;
		private System.Windows.Forms.Label objYLabel;
		private System.Windows.Forms.Label label3;
		public System.Windows.Forms.TextBox objZText;
		private System.Windows.Forms.Label label4;
		public System.Windows.Forms.ComboBox objTypeBox;
		private System.Windows.Forms.Label label5;
		public System.Windows.Forms.TextBox objYText;
		private System.Windows.Forms.Label objZLabel;
		public System.Windows.Forms.TextBox objWidthText;
		private System.Windows.Forms.Label label7;
		public System.Windows.Forms.TextBox objHeightText;
		private System.Windows.Forms.Label label8;
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;
		public frmPropertiesArea(cArea aArea)
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();
			//
			// TODO: Add any constructor code after InitializeComponent call
			//
			mArea = aArea;
			objNameText.Text = aArea.msName;
			objActiveBox.SelectedIndex = aArea.mbActive?1:0;

			objHeightText.Text = aArea.mfHeight.ToString();
			objWidthText.Text = aArea.mfWidth.ToString();

			objXLabel.Text = ((cAreaType)aArea.mAForm.mlstTypes[aArea.mlTypeNum]).msDesc[0];
			objXText.Text = aArea.mfSizeX.ToString();

			objYLabel.Text = ((cAreaType)aArea.mAForm.mlstTypes[aArea.mlTypeNum]).msDesc[1];
			objYText.Text = aArea.mfSizeY.ToString();

			objZLabel.Text = ((cAreaType)aArea.mAForm.mlstTypes[aArea.mlTypeNum]).msDesc[2];
			objZText.Text = aArea.mfSizeZ.ToString();

			foreach(string sN in aArea.mAForm.objTypeList.Items)
			{
				objTypeBox.Items.Add(sN);
			}
			objTypeBox.SelectedIndex = aArea.mlTypeNum;
	   }
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}
		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.objNameLabel = new System.Windows.Forms.Label();
			this.label1 = new System.Windows.Forms.Label();
			this.objNameText = new System.Windows.Forms.TextBox();
			this.objXText = new System.Windows.Forms.TextBox();
			this.objOkButton = new System.Windows.Forms.Button();
			this.objCancelButtom = new System.Windows.Forms.Button();
			this.objXLabel = new System.Windows.Forms.Label();
			this.label6 = new System.Windows.Forms.Label();
			this.objActiveBox = new System.Windows.Forms.ComboBox();
			this.objYLabel = new System.Windows.Forms.Label();
			this.objYText = new System.Windows.Forms.TextBox();
			this.label3 = new System.Windows.Forms.Label();
			this.objZLabel = new System.Windows.Forms.Label();
			this.objZText = new System.Windows.Forms.TextBox();
			this.label4 = new System.Windows.Forms.Label();
			this.objTypeBox = new System.Windows.Forms.ComboBox();
			this.label5 = new System.Windows.Forms.Label();
			this.objWidthText = new System.Windows.Forms.TextBox();
			this.label7 = new System.Windows.Forms.Label();
			this.objHeightText = new System.Windows.Forms.TextBox();
			this.label8 = new System.Windows.Forms.Label();
			this.SuspendLayout();
			//
			// objNameLabel
			//
			this.objNameLabel.Location = new System.Drawing.Point(16, 16);
			this.objNameLabel.Name = "objNameLabel";
			this.objNameLabel.Size = new System.Drawing.Size(64, 16);
			this.objNameLabel.TabIndex = 0;
			this.objNameLabel.Text = "Name:";
			//
			// label1
			//
			this.label1.Location = new System.Drawing.Point(16, 200);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(48, 16);
			this.label1.TabIndex = 1;
			this.label1.Text = "Var X:";
			//
			// objNameText
			//
			this.objNameText.Location = new System.Drawing.Point(104, 16);
			this.objNameText.MaxLength = 40;
			this.objNameText.Name = "objNameText";
			this.objNameText.Size = new System.Drawing.Size(104, 20);
			this.objNameText.TabIndex = 3;
			this.objNameText.Text = "";
			//
			// objXText
			//
			this.objXText.Location = new System.Drawing.Point(104, 192);
			this.objXText.MaxLength = 40;
			this.objXText.Name = "objXText";
			this.objXText.Size = new System.Drawing.Size(104, 20);
			this.objXText.TabIndex = 4;
			this.objXText.Text = "";
			//
			// objOkButton
			//
			this.objOkButton.Location = new System.Drawing.Point(24, 432);
			this.objOkButton.Name = "objOkButton";
			this.objOkButton.Size = new System.Drawing.Size(72, 24);
			this.objOkButton.TabIndex = 7;
			this.objOkButton.Text = "OK";
			this.objOkButton.Click += new System.EventHandler(this.objOkButton_Click);
			//
			// objCancelButtom
			//
			this.objCancelButtom.Location = new System.Drawing.Point(120, 432);
			this.objCancelButtom.Name = "objCancelButtom";
			this.objCancelButtom.Size = new System.Drawing.Size(72, 24);
			this.objCancelButtom.TabIndex = 8;
			this.objCancelButtom.Text = "Cancel";
			this.objCancelButtom.Click += new System.EventHandler(this.objCancelButtom_Click);
			//
			// objXLabel
			//
			this.objXLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.objXLabel.Location = new System.Drawing.Point(16, 160);
			this.objXLabel.Name = "objXLabel";
			this.objXLabel.Size = new System.Drawing.Size(200, 32);
			this.objXLabel.TabIndex = 12;
			this.objXLabel.Text = "Description...";
			//
			// label6
			//
			this.label6.Location = new System.Drawing.Point(16, 48);
			this.label6.Name = "label6";
			this.label6.Size = new System.Drawing.Size(48, 16);
			this.label6.TabIndex = 15;
			this.label6.Text = "Active:";
			//
			// objActiveBox
			//
			this.objActiveBox.Items.AddRange(new object[] {
															  "False",
															  "True"});
			this.objActiveBox.Location = new System.Drawing.Point(104, 48);
			this.objActiveBox.Name = "objActiveBox";
			this.objActiveBox.Size = new System.Drawing.Size(104, 21);
			this.objActiveBox.TabIndex = 16;
			//
			// objYLabel
			//
			this.objYLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.objYLabel.Location = new System.Drawing.Point(16, 224);
			this.objYLabel.Name = "objYLabel";

Answer: this.objYLabel.Size = new System.Drawing.Size(200, 32);


Context:
// CommonSecurityDescriptorTest.cs - NUnit Test Cases for CommonSecurityDescriptor
//
// Authors:
//	James Bellinger  <jfb@zer7.com>
//
// Copyright (C) 2012 James Bellinger
using System;
using System.Collections.Generic;
using System.Security.AccessControl;
using System.Security.Principal;
using NUnit.Framework;
namespace MonoTests.System.Security.AccessControl
{
	[TestFixture]
	public class CommonSecurityDescriptorTest
	{
		[Test]
		public void DefaultOwnerAndGroup ()
		{
			CommonSecurityDescriptor csd = new CommonSecurityDescriptor
				(false, false, ControlFlags.None, null, null, null, null);
			Assert.IsNull (csd.Owner);
			Assert.IsNull (csd.Group);
			Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
			                 | ControlFlags.SelfRelative, csd.ControlFlags);
		}
		[Test]
		public void GetBinaryForm ()
		{
			CommonSecurityDescriptor csd = new CommonSecurityDescriptor
				(false, false, ControlFlags.None, null, null, null, null);
			Assert.AreEqual (20, csd.BinaryLength);
			byte[] binaryForm = new byte[csd.BinaryLength];
			csd.GetBinaryForm (binaryForm, 0);
			Assert.AreEqual (ControlFlags.DiscretionaryAclPresent | ControlFlags.SelfRelative,
			                 csd.ControlFlags);
			// The default 'Allow Everyone Full Access' serializes as NOT having a
			// DiscretionaryAcl, as the above demonstrates (byte 3 is 0 not 4).
			Assert.AreEqual (new byte[20] {
				1, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
			}, binaryForm);
			// Changing SystemAcl protection does nothing special.
			csd.SetSystemAclProtection (true, true);
			Assert.AreEqual (20, csd.BinaryLength);
			// Modifying the DiscretionaryAcl (even effective no-ops like this) causes serialization.
			csd.SetDiscretionaryAclProtection (false, true);
			Assert.AreEqual (48, csd.BinaryLength);
		}
		[Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
		public void GetBinaryFormOffset ()
		{
			CommonSecurityDescriptor csd = new CommonSecurityDescriptor
				(false, false, ControlFlags.None, null, null, null, null);
			csd.GetBinaryForm (new byte[csd.BinaryLength], 1);
		}
		[Test, ExpectedException (typeof (ArgumentNullException))]
		public void GetBinaryFormNull ()
		{
			CommonSecurityDescriptor csd = new CommonSecurityDescriptor
				(false, false, ControlFlags.None, null, null, null, null);
			csd.GetBinaryForm (null, 0);
		}
		[Test]
		public void AefaModifiedFlagIsStoredOnDiscretionaryAcl ()
		{
			CommonSecurityDescriptor csd1, csd2;
			// Incidentally this shows the DiscretionaryAcl is NOT cloned.
			csd1 = new CommonSecurityDescriptor (false, false, ControlFlags.None, null, null, null, null);
			csd2 = new CommonSecurityDescriptor (false, false, ControlFlags.None, null, null, null, csd1.DiscretionaryAcl);
			Assert.AreSame (csd1.DiscretionaryAcl, csd2.DiscretionaryAcl);
			Assert.AreEqual ("", csd1.GetSddlForm (AccessControlSections.Access));
			csd2.SetDiscretionaryAclProtection (false, true);
			Assert.AreEqual ("D:(A;;0xffffffff;;;WD)", csd1.GetSddlForm (AccessControlSections.Access));
			Assert.AreEqual ("D:(A;;0xffffffff;;;WD)", csd2.GetSddlForm (AccessControlSections.Access));
		}
		[Test]
		public void AefaRoundtrip ()
		{
			CommonSecurityDescriptor csd;
			csd = new CommonSecurityDescriptor (false, false, ControlFlags.None, null, null, null, null);
			Assert.AreEqual (20, csd.BinaryLength);
			byte[] binaryForm1 = new byte[csd.BinaryLength];
			csd.GetBinaryForm (binaryForm1, 0);
			csd = new CommonSecurityDescriptor (false, false, new RawSecurityDescriptor (binaryForm1, 0));
			byte[] binaryForm2 = new byte[csd.BinaryLength];
			csd.GetBinaryForm (binaryForm2, 0);
			Assert.AreEqual (binaryForm1, binaryForm2);
		}
		[Test]
		public void GetSddlFormAefaRemovesDacl ()
		{
			CommonSecurityDescriptor csd = new CommonSecurityDescriptor
				(false, false, ControlFlags.None, null, null, null, null);
			Assert.AreEqual (1, csd.DiscretionaryAcl.Count);
			Assert.AreEqual ("", csd.GetSddlForm (AccessControlSections.Access));
			Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
			                 | ControlFlags.SelfRelative,
			                 csd.ControlFlags);
			Assert.AreSame (csd.DiscretionaryAcl, csd.DiscretionaryAcl);
			Assert.AreNotSame (csd.DiscretionaryAcl[0], csd.DiscretionaryAcl[0]);
			Assert.AreEqual ("", csd.GetSddlForm (AccessControlSections.Access));
			csd.SetDiscretionaryAclProtection (false, true);
			Assert.AreEqual ("D:(A;;0xffffffff;;;WD)", csd.GetSddlForm (AccessControlSections.Access));
			Assert.AreSame (csd.DiscretionaryAcl, csd.DiscretionaryAcl);
			Assert.AreNotSame (csd.DiscretionaryAcl[0], csd.DiscretionaryAcl[0]);
			Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
			                 | ControlFlags.SelfRelative,
			                 csd.ControlFlags);
			csd.SetDiscretionaryAclProtection (true, true);
			Assert.AreEqual (1, csd.DiscretionaryAcl.Count);
			Assert.AreEqual ("D:P(A;;0xffffffff;;;WD)", csd.GetSddlForm (AccessControlSections.Access));
			Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
			                 | ControlFlags.DiscretionaryAclProtected
			                 | ControlFlags.SelfRelative,
			                 csd.ControlFlags);
			csd.SetDiscretionaryAclProtection (false, false);
			Assert.AreEqual (1, csd.DiscretionaryAcl.Count);
			Assert.AreEqual ("D:(A;;0xffffffff;;;WD)", csd.GetSddlForm (AccessControlSections.Access));
			Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
			                 | ControlFlags.SelfRelative,
			                 csd.ControlFlags);
		}
		[Test, ExpectedException (typeof (ArgumentException))]
		public void ContainerAndDSConsistencyEnforcedA ()
		{
			SecurityIdentifier userSid = new SecurityIdentifier (WellKnownSidType.LocalSystemSid, null);
			SecurityIdentifier groupSid = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
			DiscretionaryAcl dacl = new DiscretionaryAcl (true, true, 0);
			new CommonSecurityDescriptor (true, false, ControlFlags.None, userSid, groupSid, null, dacl);
		}
		[Test, ExpectedException (typeof (ArgumentException))]
		public void ContainerAndDSConsistencyEnforcedB ()
		{
			SecurityIdentifier userSid = new SecurityIdentifier (WellKnownSidType.LocalSystemSid, null);
			SecurityIdentifier groupSid = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
			SystemAcl sacl = new SystemAcl (false, false, 0);
			new CommonSecurityDescriptor (true, false, ControlFlags.None, userSid, groupSid, sacl, null);
		}
		[Test, ExpectedException (typeof (ArgumentException))]
		public void ContainerAndDSConsistencyEnforcedInSetter ()
		{
			SecurityIdentifier userSid = new SecurityIdentifier (WellKnownSidType.LocalSystemSid, null);
			SecurityIdentifier groupSid = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
			CommonSecurityDescriptor csd = new CommonSecurityDescriptor
				(true, false, ControlFlags.None, userSid, groupSid, null, null);
			csd.DiscretionaryAcl = new DiscretionaryAcl (true, true, 0);
		}
		[Test]
		public void DefaultDaclIsAllowEveryoneFullAccess ()
		{
			SecurityIdentifier userSid = new SecurityIdentifier ("SY");
			SecurityIdentifier groupSid = new SecurityIdentifier ("BA");
			SecurityIdentifier everyoneSid = new SecurityIdentifier ("WD");
			CommonSecurityDescriptor csd; DiscretionaryAcl dacl; CommonAce ace;
			csd = new CommonSecurityDescriptor (false, false, ControlFlags.None, userSid, groupSid, null, null);
			dacl = csd.DiscretionaryAcl;
			Assert.AreEqual (1, dacl.Count);
			ace = (CommonAce)dacl [0];
			Assert.AreEqual (-1, ace.AccessMask);
			Assert.AreEqual (AceFlags.None, ace.AceFlags);
			Assert.AreEqual (AceType.AccessAllowed, ace.AceType);
			Assert.AreEqual (20, ace.BinaryLength);
			Assert.IsFalse (ace.IsCallback);
			Assert.IsFalse (ace.IsInherited);
			Assert.AreEqual (0, ace.OpaqueLength);
			Assert.AreEqual (ace.SecurityIdentifier, everyoneSid);
			csd = new CommonSecurityDescriptor (true, false, ControlFlags.None, userSid, groupSid, null, null);
			dacl = csd.DiscretionaryAcl;
			Assert.AreEqual (1, dacl.Count);
			ace = (CommonAce)dacl [0];
			Assert.AreEqual (-1, ace.AccessMask);
			Assert.AreEqual (AceFlags.ObjectInherit | AceFlags.ContainerInherit, ace.AceFlags);
			Assert.AreEqual (AceType.AccessAllowed, ace.AceType);
			Assert.AreEqual (20, ace.BinaryLength);
			Assert.IsFalse (ace.IsCallback);
			Assert.IsFalse (ace.IsInherited);
			Assert.AreEqual (0, ace.OpaqueLength);
			Assert.AreEqual (ace.SecurityIdentifier, everyoneSid);
		}
		[Test]
		public void PurgeDefaultDacl ()
		{

Answer: SecurityIdentifier userSid = new SecurityIdentifier ("SY");


Context:
/**
 * Copyright (c) 2002-2012 "Neo Technology,"
 * Network Engine for Objects in Lund AB [http://neotechnology.com]
 *
 * This file is part of Neo4j.
 *
 * Neo4j is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.neo4j.graphmatching;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.neo4j.graphdb.Node;
import org.neo4j.graphmatching.filter.AbstractFilterExpression;
import org.neo4j.graphmatching.filter.FilterBinaryNode;
import org.neo4j.graphmatching.filter.FilterExpression;
import org.neo4j.graphmatching.filter.FilterValueGetter;
import org.neo4j.helpers.Predicate;
import org.neo4j.helpers.collection.FilteringIterable;
/**
 * The PatternMatcher is the engine that performs the matching of a graph
 * pattern with the actual graph.
 */
@Deprecated
public class PatternMatcher
{
	private static PatternMatcher matcher = new PatternMatcher();
	private PatternMatcher()
	{
	}
    /**
     * Get the sole instance of the {@link PatternMatcher}.
     *
     * @return the instance of {@link PatternMatcher}.
     */
	public static PatternMatcher getMatcher()
	{
		return matcher;
	}
    /**
     * Find occurrences of the pattern defined by the given {@link PatternNode}
     * where the given {@link PatternNode} starts matching at the given
     * {@link Node}.
     *
     * @param start the {@link PatternNode} to start matching at.
     * @param startNode the {@link Node} to start matching at.
     * @return all matching instances of the pattern.
     */
    public Iterable<PatternMatch> match( PatternNode start,
        Node startNode )
    {
        return match( start, startNode, null );
    }
    /**
     * Find occurrences of the pattern defined by the given {@link PatternNode}
     * where the given {@link PatternNode} starts matching at the given
     * {@link Node}.
     *
     * @param start the {@link PatternNode} to start matching at.
     * @param startNode the {@link Node} to start matching at.
     * @param objectVariables mapping from names to {@link PatternNode}s.
     * @return all matching instances of the pattern.
     */
	public Iterable<PatternMatch> match( PatternNode start,
		Node startNode, Map<String, PatternNode> objectVariables )
	{
		return match( start, startNode, objectVariables,
		    ( Collection<PatternNode> ) null );
	}
    /**
     * Find occurrences of the pattern defined by the given {@link PatternNode}
     * where the given {@link PatternNode} starts matching at the given
     * {@link Node}.
     *
     * @param start the {@link PatternNode} to start matching at.
     * @param objectVariables mapping from names to {@link PatternNode}s.
     * @param optional nodes that form sub-patterns connected to this pattern.
     * @return all matching instances of the pattern.
     */
    public Iterable<PatternMatch> match( PatternNode start,
            Map<String, PatternNode> objectVariables,
            PatternNode... optional )
    {
        return match( start, objectVariables,
            Arrays.asList( optional ) );
    }
    /**
     * Find occurrences of the pattern defined by the given {@link PatternNode}
     * where the given {@link PatternNode} starts matching at the given
     * {@link Node}.
     *
     * @param start the {@link PatternNode} to start matching at.
     * @param objectVariables mapping from names to {@link PatternNode}s.
     * @param optional nodes that form sub-patterns connected to this pattern.
     * @return all matching instances of the pattern.
     */
	public Iterable<PatternMatch> match( PatternNode start,
	        Map<String, PatternNode> objectVariables,
	        Collection<PatternNode> optional )
    {
	    Node startNode = start.getAssociation();
        if ( startNode == null )
        {
            throw new IllegalStateException(
                    "Associating node for start pattern node is null" );
        }
	    return match( start, startNode, objectVariables, optional );
    }
    /**
     * Find occurrences of the pattern defined by the given {@link PatternNode}
     * where the given {@link PatternNode} starts matching at the given
     * {@link Node}.
     *
     * @param start the {@link PatternNode} to start matching at.
     * @param startNode the {@link Node} to start matching at.
     * @param objectVariables mapping from names to {@link PatternNode}s.
     * @param optional nodes that form sub-patterns connected to this pattern.
     * @return all matching instances of the pattern.
     */
	public Iterable<PatternMatch> match( PatternNode start,
		Node startNode, Map<String, PatternNode> objectVariables,
		Collection<PatternNode> optional )
	{
        Node currentStartNode = start.getAssociation();
        if ( currentStartNode != null && !currentStartNode.equals( startNode ) )
        {
            throw new IllegalStateException(
                    "Start patter node already has associated " +
                    currentStartNode + ", can not start with " + startNode );
        }
	    Iterable<PatternMatch> result = null;
		if ( optional == null || optional.size() < 1 )
		{
			result = new PatternFinder( this, start, startNode );
		}
		else
		{
			result = new PatternFinder( this, start, startNode, false,
			    optional );
		}
		if ( objectVariables != null )
		{
    		// Uses the FILTER expressions
    		result = new FilteredPatternFinder( result, objectVariables );
		}
		return result;
	}
    /**
     * Find occurrences of the pattern defined by the given {@link PatternNode}
     * where the given {@link PatternNode} starts matching at the given
     * {@link Node}.
     *
     * @param start the {@link PatternNode} to start matching at.
     * @param startNode the {@link Node} to start matching at.
     * @param objectVariables mapping from names to {@link PatternNode}s.
     * @param optional nodes that form sub-patterns connected to this pattern.
     * @return all matching instances of the pattern.
     */
	public Iterable<PatternMatch> match( PatternNode start,
		Node startNode, Map<String, PatternNode> objectVariables,
		PatternNode... optional )
	{
		return match( start, startNode, objectVariables,
		    Arrays.asList( optional ) );
	}
	private static class SimpleRegexValueGetter implements FilterValueGetter
	{
	    private PatternMatch match;
	    private Map<String, PatternNode> labelToNode =
	        new HashMap<String, PatternNode>();
	    private Map<String, String> labelToProperty =
	        new HashMap<String, String>();
	    SimpleRegexValueGetter( Map<String, PatternNode> objectVariables,
	        PatternMatch match, FilterExpression[] expressions )
	    {
            this.match = match;
            for ( FilterExpression expression : expressions )
            {
                mapFromExpression( expression );
            }
            this.labelToNode = objectVariables;
	    }
	    private void mapFromExpression( FilterExpression expression )
	    {
	        if ( expression instanceof FilterBinaryNode )
	        {
	            FilterBinaryNode node = ( FilterBinaryNode ) expression;
	            mapFromExpression( node.getLeftExpression() );
	            mapFromExpression( node.getRightExpression() );
	        }
	        else
	        {
	            AbstractFilterExpression pattern =
	                ( AbstractFilterExpression ) expression;
	            labelToProperty.put( pattern.getLabel(),
	                pattern.getProperty() );
	        }
	    }
        public String[] getValues( String label )
        {
            PatternNode pNode = labelToNode.get( label );
            if ( pNode == null )
            {
                throw new RuntimeException( "No node for label '" + label +
                    "'" );
            }
            Node node = this.match.getNodeFor( pNode );
            String propertyKey = labelToProperty.get( label );
            if ( propertyKey == null )
            {
                throw new RuntimeException( "No property key for label '" +
                    label + "'" );
            }
            Object rawValue = node.getProperty( propertyKey, null );
            if ( rawValue == null )
            {
                return new String[ 0 ];
            }
            Collection<Object> values =
                ArrayPropertyUtil.propertyValueToCollection( rawValue );
            String[] result = new String[ values.size() ];
            int counter = 0;
            for ( Object value : values )
            {
                result[ counter++ ] = ( String ) value;
            }
            return result;
        }
	}
	private static class FilteredPatternFinder
	    extends FilteringIterable<PatternMatch>
	{
        public FilteredPatternFinder( Iterable<PatternMatch> source,
            final Map<String, PatternNode> objectVariables )
        {

Answer: super( source, new Predicate<PatternMatch>()


Context:
import os
import zmq
import warnings
TIMEOUT = 1000  # milliseconds
VERBOSE = False
RETRY = True  # Should we try to get another server if we can't connect?
SERVERFILE = "serverlist.dat" # Base name of the file containing  server names
if __name__ == '__main__':
    VERBOSE = True
def printV(*args):
    if VERBOSE:
        for arg in args:
            print arg,
        print ''
def getBasePath(): # Get the base directory of this script
    return __file__[:__file__.rfind("clientBase.py")]
def getServerFile(): # Return the full path the the server list file
    return os.path.join(getBasePath(), SERVERFILE)
def generateConfig(): # generates the config and server files if not found
    serverFile = getServerFile()
    if os.path.isfile(serverFile):
        printV("Server List Found at %s" % serverFile)
    else:
        printV("No Server List Found")
        printV("Generating New Server List at %s" % serverFile)
        with open(serverFile,'wb') as f:
            f.write("echidna tcp://108.52.218.107:5001")
class SDSSError(Exception):  # custom SDSSError that relates to serverside issues
    def __init__(self, message, errors=None):
        super(SDSSError, self).__init__(message)
        self.errors = errors
class ServerList(dict):  # dictionary like class that manages the possible servers
    def __init__(self, *args, **kwargs):
        super(ServerList, self).__init__(*args, **kwargs)
        self.best = None
        self.priority = {}
    def addServer(self, name, address, priority):  # add a server to our list of servers
        server = {"address": address, "priority": priority}
        self[name] = server
        self.priority[priority] = name
    def addServersFromFile(self, filename):
        servers = []
        priority = 0
        with open(filename, 'rb') as f:
            for line in f:
                name, address = line.strip().split()
                self.addServer(name, address, priority)
                priority += 1
    def saveServersToFile(self, filename):
        lines = []
        for p in sorted(self.priority.keys()):
            name = self.priority[p]
            address = self[name]['address']
            lines.append(' '.join((name, address)))
        with open(filename, 'wb') as f:
            f.write('\n'.join(lines))
    def testServer(self, server):
        try:
            context = zmq.Context()
            socket = context.socket(zmq.REQ)
            socket.LINGER = False
            socket.connect(server['address'])
            socket.send(b"ping\n", flags=zmq.NOBLOCK)
            if socket.poll(timeout=1000, flags=zmq.POLLIN):
                return True
            else:
                return False
        except zmq.ZMQError as e:
            raise SDSSError(e.message, e.errno)
    def getBestServer(self):  # determine the best server
        for key, server in sorted(self.items(), key=lambda x: x[1]['priority']):
            isGood = self.testServer(server)
            if isGood:
                printV("Best Server is %s" % key)
                self.best = server['address']
                break
        else:
            self.best = None
            raise SDSSError("No good servers available at the moment", self.best)
    def setBestServer(self, server):  # manually override the best server
        printV("Testing Server %s" % server)
        isGood = self.testServer(self[server])
        if isGood:
            self.best = self[server]['address']
            printV("%s is now connected" % server)
        else:
            raise SDSSError("Bad Server: %s" % server, server)
generateConfig() # Setup the server list and config if needed
servers = ServerList() # Instantiate a new server list
servers.addServersFromFile(getServerFile()) # Add servers from our server list
servers.getBestServer() # Find the best server based on priority and availability
def getSocket():
    context = zmq.Context()
    socket = context.socket(zmq.REQ)
    socket.LINGER = False
    socket.connect(servers.best)
    return socket
def zmqSocketDecorator(func):  # a decorator that handles the zmq sockets and raises SDSS exceptions
    def wrapper(*args, **kwargs):
        try:
            socket = getSocket()
            return func(socket, *args, **kwargs)
        except zmq.ZMQError as e:
            raise SDSSError(e.message, e.errno)
    return wrapper
@zmqSocketDecorator
def getCommandResult(socket, cmd):  # send a command to the server and return the result
    global RETRY
    socket.send(cmd)
    if socket.poll(timeout=TIMEOUT, flags=zmq.POLLIN):
        result = socket.recv_pyobj(flags=zmq.NOBLOCK)
    else:
        if RETRY:
            printV("Server Disconnected.  Attempting to Connect to Another Server")
            servers.getBestServer()
            RETRY = False
            result = getCommandResult(cmd)
            RETRY = True
            return result
        else:
            raise SDSSError("Socket timed out", TIMEOUT)
    if isinstance(result, Exception):
        raise SDSSError(*result.args)
    return result
def createCommand(server_func, *args):  # get the command string for a function and it's arguments
    if len(args):
        args = " ".join(map(str, args))
    else:
        args = ''
    cmd = b"%s\n%s" % (server_func, args)
    return cmd
def isValid(server_func):  # checks if a server_func is valid
    cmd = createCommand('isValid', server_func)
    result = getCommandResult(cmd)
    return result
def commandArgCount(server_func):  # gets information about the server func
    cmd = createCommand('argCount', server_func)
    result = getCommandResult(cmd)
    return result
def _createFunction(server_func, docstr=None):
    # Create a function object that acts on a server side func with name 'server_func'
    if isValid(server_func):
        nargs = commandArgCount(server_func) - 1
    else:
        raise SDSSError("Invalid Function: %s" % server_func, server_func)
    def Func(*args):
        if len(args) != nargs:
            message = "%s takes exactly %i arguments (%i given)" % (server_func, nargs, len(args))
            raise TypeError(message)
        if docstr is not None:
            Func.__doc__ = docstr
        cmd = createCommand(server_func, *args)
        result = getCommandResult(cmd)
        return result
    return Func
def createFunction(server_func, docstr=None):
    def initialFunc(*args):
        initalFunc = _createFunction(server_func, docstr)
        return initalFunc(*args)
    return initialFunc
# define our client-side functions below
getRandLC = createFunction("randLC",
                           """
args: None
returns:
    filename, redshift, data (tuple):
        filename (str): name of the file on disk
        redshift (float): redshift of the object
        data (numpy structure array): structured array of the data from the LC file
""")
getLC = createFunction("getLC",
                       """
args:
    ID (str): SDSS J2000 name
returns:
    filename, redshift, data (tuple):
        filename (str): name of the file on disk
        redshift (float): redshift of the object
        data (numpy structure array): structured array of the data from the LC file
""")
getIDList = createFunction("IDList",
                           """
args: None
returns:
    IDList (list): List of strings of SDSS Objects names on disk
""")
getNearestLC = createFunction('getNearestLC',
                              """
args:
    ID (str): SDSS J200 name
    tol (float): matching tolerance in degrees
returns:
    filename, reshift, data (tuple):
        see above
""")
if __name__ == '__main__':
    import sys
    if len(sys.argv) == 1:
        print "Test"
    if sys.argv[1] == '--check':
        for name in sys.argv[2:]:
            try:
                getNearestLC(name, 2/60.0/60.0)
            except SDSSError as e:
                if 'No objects in list' in e.message:
                    print "LC does not exist in data base", 0, name
            except IndexError as e:
                print "No File Specified"
            else:
                print "LC does exist in database     ", 1, name
    elif sys.argv[1] == '--rand':
        print getRandLC()

Answer: elif sys.argv[1] == '--list':


Context:
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2022 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/
package io.questdb.cutlass.text;
import io.questdb.cairo.ColumnType;
import io.questdb.cutlass.json.JsonException;
import io.questdb.cutlass.json.JsonLexer;
import io.questdb.cutlass.json.JsonParser;
import io.questdb.cutlass.text.types.TypeAdapter;
import io.questdb.cutlass.text.types.TypeManager;
import io.questdb.griffin.SqlKeywords;
import io.questdb.log.Log;
import io.questdb.log.LogFactory;
import io.questdb.std.*;
import io.questdb.std.datetime.DateLocale;
import io.questdb.std.datetime.DateLocaleFactory;
import io.questdb.std.datetime.microtime.TimestampFormatFactory;
import io.questdb.std.datetime.millitime.DateFormatFactory;
import io.questdb.std.str.AbstractCharSequence;
import java.io.Closeable;
public class TextMetadataParser implements JsonParser, Mutable, Closeable {
    private static final Log LOG = LogFactory.getLog(TextMetadataParser.class);
    private static final int S_NEED_ARRAY = 1;
    private static final int S_NEED_OBJECT = 2;
    private static final int S_NEED_PROPERTY = 3;
    private static final int P_NAME = 1;
    private static final int P_TYPE = 2;
    private static final int P_PATTERN = 3;
    private static final int P_LOCALE = 4;
    private static final int P_UTF8 = 5;
    private static final int P_INDEX = 6;
    private static final CharSequenceIntHashMap propertyNameMap = new CharSequenceIntHashMap();
    private final DateLocaleFactory dateLocaleFactory;
    private final ObjectPool<FloatingCharSequence> csPool;
    private final DateFormatFactory dateFormatFactory;
    private final TimestampFormatFactory timestampFormatFactory;
    private final ObjList<CharSequence> columnNames;
    private final ObjList<TypeAdapter> columnTypes;
    private final TypeManager typeManager;
    private final DateLocale dateLocale;
    private int state = S_NEED_ARRAY;
    private CharSequence name;
    private int type = -1;
    private CharSequence pattern;
    private CharSequence locale;
    private int propertyIndex;
    private long buf;
    private long bufCapacity = 0;
    private int bufSize = 0;
    private CharSequence tableName;
    private int localePosition;
    private boolean utf8 = false;
    private boolean index = false;
    public TextMetadataParser(TextConfiguration textConfiguration, TypeManager typeManager) {
        this.columnNames = new ObjList<>();
        this.columnTypes = new ObjList<>();
        this.csPool = new ObjectPool<>(FloatingCharSequence::new, textConfiguration.getMetadataStringPoolCapacity());
        this.dateLocaleFactory = typeManager.getInputFormatConfiguration().getDateLocaleFactory();
        this.dateFormatFactory = typeManager.getInputFormatConfiguration().getDateFormatFactory();
        this.timestampFormatFactory = typeManager.getInputFormatConfiguration().getTimestampFormatFactory();
        this.typeManager = typeManager;
        this.dateLocale = textConfiguration.getDefaultDateLocale();
    }
    @Override
    public void clear() {
        bufSize = 0;
        state = S_NEED_ARRAY;
        columnNames.clear();
        columnTypes.clear();
        csPool.clear();
        clearStage();
    }
    @Override
    public void close() {
        clear();
        if (bufCapacity > 0) {
            Unsafe.free(buf, bufCapacity, MemoryTag.NATIVE_DEFAULT);
            bufCapacity = 0;
        }
    }
    public ObjList<CharSequence> getColumnNames() {
        return columnNames;
    }
    public ObjList<TypeAdapter> getColumnTypes() {
        return columnTypes;
    }
    @Override
    public void onEvent(int code, CharSequence tag, int position) throws JsonException {
        switch (code) {
            case JsonLexer.EVT_ARRAY_START:
                if (state != S_NEED_ARRAY) {
                    throw JsonException.$(position, "Unexpected array");
                }
                state = S_NEED_OBJECT;
                break;
            case JsonLexer.EVT_OBJ_START:
                if (state != S_NEED_OBJECT) {
                    throw JsonException.$(position, "Unexpected object");
                }
                state = S_NEED_PROPERTY;
                break;
            case JsonLexer.EVT_NAME:
                this.propertyIndex = propertyNameMap.get(tag);
                if (this.propertyIndex == -1) {
                    LOG.info().$("unknown [table=").$(tableName).$(", tag=").$(tag).$(']').$();
                }
                break;
            case JsonLexer.EVT_VALUE:
                switch (propertyIndex) {
                    case P_NAME:
                        name = copy(tag);
                        break;
                    case P_TYPE:
                        type = ColumnType.tagOf(tag);
                        if (type == -1) {
                            throw JsonException.$(position, "Invalid type");
                        }
                        break;
                    case P_PATTERN:
                        pattern = copy(tag);
                        break;
                    case P_LOCALE:
                        locale = copy(tag);
                        localePosition = position;
                        break;
                    case P_UTF8:
                        utf8 = SqlKeywords.isTrueKeyword(tag);
                        break;
                    case P_INDEX:
                        index = SqlKeywords.isTrueKeyword(tag);
                        break;
                    default:
                        LOG.info().$("ignoring [table=").$(tableName).$(", value=").$(tag).$(']').$();
                        break;
                }
                break;
            case JsonLexer.EVT_OBJ_END:
                state = S_NEED_OBJECT;
                createImportedType(position);
                break;
            case JsonLexer.EVT_ARRAY_VALUE:
                throw JsonException.$(position, "Must be an object");
            default:
                break;
        }
    }
    private static void strcpyw(final CharSequence value, final int len, final long address) {
        for (int i = 0; i < len; i++) {
            Unsafe.getUnsafe().putChar(address + ((long) i << 1), value.charAt(i));
        }
    }
    private static void checkInputs(int position, CharSequence name, int type) throws JsonException {
        if (name == null) {
            throw JsonException.$(position, "Missing 'name' property");
        }
        if (type == -1) {
            throw JsonException.$(position, "Missing 'type' property");
        }
    }
    private void clearStage() {
        name = null;
        type = -1;
        pattern = null;
        locale = null;
        localePosition = 0;
        utf8 = false;
        index = false;
    }
    private CharSequence copy(CharSequence tag) {
        final int l = tag.length() * 2;
        final long n = bufSize + l;
        if (n > bufCapacity) {
            long ptr = Unsafe.malloc(n * 2, MemoryTag.NATIVE_DEFAULT);
            Vect.memcpy(ptr, buf, bufSize);
            if (bufCapacity > 0) {
                Unsafe.free(buf, bufCapacity, MemoryTag.NATIVE_DEFAULT);
            }
            buf = ptr;
            bufCapacity = n * 2;
        }
        strcpyw(tag, l / 2, buf + bufSize);
        CharSequence cs = csPool.next().of(bufSize, l / 2);
        bufSize += l;
        return cs;
    }
    private void createImportedType(int position) throws JsonException {
        checkInputs(position, name, type);
        columnNames.add(name);
        switch (ColumnType.tagOf(type)) {
            case ColumnType.DATE:
                DateLocale dateLocale = locale == null ? this.dateLocale : dateLocaleFactory.getLocale(locale);
                if (dateLocale == null) {
                    throw JsonException.$(localePosition, "Invalid date locale");
                }
                // date pattern is required
                if (pattern == null) {
                    throw JsonException.$(0, "DATE format pattern is required");
                }
                columnTypes.add(typeManager.nextDateAdapter().of(dateFormatFactory.get(pattern), dateLocale));
                break;
            case ColumnType.TIMESTAMP:
                DateLocale timestampLocale =
                        locale == null ?
                                this.dateLocale
                                : dateLocaleFactory.getLocale(locale);
                if (timestampLocale == null) {
                    throw JsonException.$(localePosition, "Invalid timestamp locale");
                }
                // timestamp pattern is required

Answer: if (pattern == null) {