text:
#include "Htv.h"
#include "HtDesign.h"

namespace ht {

	// Insert register stages as appropriate to achieve timing
	//   need to decide how to number register stages
	//   need to walk statments and replace registers with appropriate register stage
	//   need to declare new registers
	//   need to connect pipelined reigsters

	////////////////////////////////////////////////////////////////////////////////////
	//  Trs is set prior to entry
	//  Insert timing registers
	//  Declare new variables (r_ and c_)
	//  Insert r_ and c_ assignment statements

	class HtInsertRegisterStages : HtWalkStmtTree
	{
	public:
		HtInsertRegisterStages(HtDesign * pHtDesign, ASTContext &Context)
			: m_pHtDesign(pHtDesign), m_context(Context), m_diags(Context.getDiagnostics()) {}

		void insertRegisterStages();

		bool walkCallback( HtStmtIter & iStmt, HtStmtIter & iInsert, bool isLoa, void * pVoid );
		void walkPostCallback( HtStmtIter & iStmt, HtStmtIter & iInsert, bool isLoa, void * pVoid );

	private:

		// if statement routines
		void setIfLhsDeclMinTrs(HtStmtIter & iStmt);
		int findIfLhsMinTrs(HtStmtIter & iStmt, bool & bLastTrs);
		void dupIfStmtForMinTrs(HtStmtIter & iOrigStmt, HtStmtIter & iNewStmt, int minTrs);
		HtStmt * dupIfClauseMinTrs( HtStmt * pStmt, int minTrs );
		void insertRegIfStmt(HtStmtIter & iIfStmt, int rdTrs, HtStmtIter & iInsert);

		void insertRegMemberRhsExpr(HtExpr * pRhsExpr, int rdTrs, HtStmtIter & iInsert);
		void insertRegMemberLhsExpr(HtExpr * pLhsExpr, int rdTrs, HtStmtIter & iInsert);

		void insertRegDecl(HtDeclList_t & moduleDeclList);
		void insertRegAssign(HtDeclList_t & moduleDeclList, HtStmtList & methodStmtList);

		HtExpr * findBaseExpr( HtExpr * pExpr );
		HtDecl * findBaseDecl( HtExpr * pExpr );

		string genTrsName(HtDecl * pDecl, int rdTrs, bool bIsCVar=false);

	private:
		HtDesign * m_pHtDesign;
		ASTContext & m_context;
		DiagnosticsEngine & m_diags;
		HtTpg * m_pMethodTpGrp;
	};

	void HtDesign::insertRegisterStages(ASTContext &Context)
	{
		HtInsertRegisterStages transform(this, Context);

		transform.insertRegisterStages();

		ExitIfError(Context);
	}

	void HtInsertRegisterStages::insertRegisterStages()
	{
		HtDeclList_t & moduleDeclList = m_pHtDesign->getScModuleDeclList();

		// walk each ScMethod in design
		HtDeclIter iDecl(m_pHtDesign->getScMethodDeclList());
		while ( !iDecl.isEol() ) {

			// create needed staging variables
			insertRegDecl(moduleDeclList);

			m_pMethodTpGrp = (*iDecl)->getTpGrp();
			assert( (*iDecl)->getBody()->getStmtClass() == Stmt::CompoundStmtClass );
			HtStmtIter iStmt ( (*iDecl)->getBody()->getStmtList() );

			HtStmtIter iInsert = iStmt.eol();

			while ( !iStmt.isEol() )
				walkStmtTree( iStmt, iInsert, false, 0 );

			// now walk decl list and generate assignments to new registers
			HtStmtList & methodStmtList = (*iDecl)->getBody()->getStmtList();

			insertRegAssign(moduleDeclList, methodStmtList);

			iDecl++;
		}
	}

	bool HtInsertRegisterStages::walkCallback( HtStmtIter & iStmt, HtStmtIter & iInsert, bool isLoa, void * pVoid )
	{
		Stmt::StmtClass stmtClass = iStmt->getStmtClass();
		switch (stmtClass) {
		case Stmt::MemberExprClass:
		case Stmt::IntegerLiteralClass:
		case Stmt::IfStmtClass:
			return false;
		case Stmt::CallExprClass:
		case Stmt::CompoundStmtClass:
		case Stmt::BinaryOperatorClass:
		case Stmt::ImplicitCastExprClass:
		case Stmt::ParenExprClass:
			return true;
		default:
			assert(0);
			break;
		}
	}

	void HtInsertRegisterStages::setIfLhsDeclMinTrs(HtStmtIter & iStmt)
	{
		//// clear minTrs for each lhs decl
		//for (HtStmtIter iThen(iStmt->getThen()->getStmtList()); !iThen.isEol(); iThen++) {
		//	assert(iThen->getStmtClass() == Stmt::BinaryOperatorClass);

		//	HtExpr * pLhsExpr = iThen->getLhs().asExpr();
		//	assert(pLhsExpr->getStmtClass() == Stmt::MemberExprClass);

		//	HtDecl * pLhsDecl = findBaseDecl( (HtExpr *)pLhsExpr );

		//	pLhsDecl->clearSgWrTrs();
		//}

		//for (HtStmtIter iElse(iStmt->getElse()->getStmtList()); !iElse.isEol(); iElse++) {
		//	assert(iElse->getStmtClass() == Stmt::BinaryOperatorClass);

		//	HtExpr * pLhsExpr = iElse->getLhs().asExpr();
		//	assert(pLhsExpr->getStmtClass() == Stmt::MemberExprClass);

		//	HtDecl * pLhsDecl = findBaseDecl( (HtExpr *)pLhsExpr );

		//	pLhsDecl->clearSgWrTrs();
		//}

		// set minTrs for each lhs decl
		//for (HtStmtIter iThen(iStmt->getThen()->getStmtList()); !iThen.isEol(); iThen++) {
		//	assert(iThen->getStmtClass() == Stmt::BinaryOperatorClass);

		//	HtExpr * pLhsExpr = iThen->getLhs().asExpr();
		//	assert(pLhsExpr->getStmtClass() == Stmt::MemberExprClass);

		//	HtDecl * pLhsDecl = findBaseDecl( (HtExpr *)pLhsExpr );

		//	pLhsDecl->setSgWrTrs( pLhsExpr->getSgTrs() );
		//}

		//for (HtStmtIter iElse(iStmt->getElse()->getStmtList()); !iElse.isEol(); iElse++) {
		//	assert(iElse->getStmtClass() == Stmt::BinaryOperatorClass);

		//	HtExpr * pLhsExpr = iElse->getLhs().asExpr();
		//	assert(pLhsExpr->getStmtClass() == Stmt::MemberExprClass);

		//	HtDecl * pLhsDecl = findBaseDecl( (HtExpr *)pLhsExpr );

		//	pLhsDecl->setSgWrTrs( pLhsExpr->getSgTrs() );
		//}
	}

	int HtInsertRegisterStages::findIfLhsMinTrs(HtStmtIter & iStmt, bool &bLastTrs)
	{
		// get minTrs for all lhs decl
		int maxTrs = -1;
		int minTrs = -1;
		for (HtStmtIter iThen(iStmt->getThen()->getStmtList()); !iThen.isEol(); iThen++) {
			assert(iThen->getStmtClass() == Stmt::BinaryOperatorClass);

			HtExpr * pLhsExpr = iThen->getLhs().asExpr();
			assert(pLhsExpr->getStmtClass() == Stmt::MemberExprClass);

			HtDecl * pLhsDecl = findBaseDecl( (HtExpr *)pLhsExpr );

			int lhsTrs = pLhsExpr->getTpSgTrs();

			if (minTrs < 0 || minTrs > lhsTrs)
				minTrs = lhsTrs;

			maxTrs = max(maxTrs, lhsTrs);
		}

		for (HtStmtIter iElse(iStmt->getElse()->getStmtList()); !iElse.isEol(); iElse++) {
			assert(iElse->getStmtClass() == Stmt::BinaryOperatorClass);

			HtExpr * pLhsExpr = iElse->getLhs().asExpr();
			assert(pLhsExpr->getStmtClass() == Stmt::MemberExprClass);

			HtDecl * pLhsDecl = findBaseDecl( (HtExpr *)pLhsExpr );

			int lhsTrs = pLhsExpr->getTpSgTrs();

			if (minTrs < 0 || minTrs > lhsTrs)
				minTrs = lhsTrs;

			maxTrs = max(maxTrs, lhsTrs);
		}

		bLastTrs = minTrs == maxTrs;
		return minTrs;
	}

	void HtInsertRegisterStages::dupIfStmtForMinTrs(HtStmtIter & iOrigStmt, HtStmtIter & iNewStmt, int minTrs)
	{
		HtStmt * pHtStmt = new HtStmt(iOrigStmt.asStmt());
		iNewStmt.insert( pHtStmt );
		iNewStmt--;

		HtExpr * pOrigCondExpr = iOrigStmt->getCond().asExpr();
		HtExpr * pDupCondExpr = new HtExpr( pOrigCondExpr );
		pDupCondExpr->setTpSgTrs( minTrs );
		pHtStmt->setCond( pDupCondExpr );

		assert(pOrigCondExpr->getBase()->getStmtClass() == Stmt::CXXThisExprClass);
		pDupCondExpr->setBase( new HtExpr( pOrigCondExpr->getBase().asExpr() ));

		pHtStmt->setThen( dupIfClauseMinTrs( iOrigStmt->getThen().asStmt(), minTrs ));
		pHtStmt->setElse( dupIfClauseMinTrs( iOrigStmt->getElse().asStmt(), minTrs ));
	}

	HtStmt * HtInsertRegisterStages::dupIfClauseMinTrs( HtStmt * pStmt, int minTrs )
	{
		if (pStmt == 0)
			return 0;

		if (pStmt->getStmtClass() == Stmt::CompoundStmtClass) {
			HtStmt * pCmpdStmt = new HtStmt( pStmt );

			HtStmtIter iStmtIter( pStmt->getStmtList() );
			for ( ; !iStmtIter.isEol(); ) {
				assert(iStmtIter->getStmtClass() == Stmt::BinaryOperatorClass);

				HtExpr * pLhsExpr = iStmtIter->getLhs().asExpr();
				if (pLhsExpr->getTpSgTrs() != minTrs) {
					iStmtIter++;
					continue;
				}

				// move statement to dup if statement
				HtStmtIter iStmt = iStmtIter++;
				HtStmt * pAssignStmt = iStmt.asStmt();
				iStmt.erase();
				pCmpdStmt->getStmtList().append( pAssignStmt );
			}

			return pCmpdStmt;
		}
		assert(0);
		return 0;
	}

	void HtInsertRegisterStages::insertRegIfStmt(HtStmtIter & iIfStmt, int rdTrs, HtStmtIter & iInsert)
	{
		insertRegMemberRhsExpr(iIfStmt->getCond().asExpr(), rdTrs, iInsert);

		for (HtStmtIter iThen(iIfStmt->getThen()->getStmtList()); !iThen.isEol(); iThen++) {
			assert(iThen->getStmtClass() == Stmt::BinaryOperatorClass);

			HtExpr * pRhsExpr = iThen->getRhs().asExpr();
			insertRegMemberRhsExpr(pRhsExpr, rdTrs, iInsert);

			HtExpr * pLhsExpr = iThen->getLhs().asExpr();
			insertRegMemberLhsExpr(pLhsExpr, rdTrs, iInsert);
		}

		for (HtStmtIter iElse(iIfStmt->getElse()->getStmtList()); !iElse.isEol(); iElse++) {
			assert(iElse->getStmtClass() == Stmt::BinaryOperatorClass);

			HtExpr * pRhsExpr = iElse->getRhs().asExpr();
			insertRegMemberRhsExpr(pRhsExpr, rdTrs, iInsert);

			HtExpr * pLhsExpr = iElse->getLhs().asExpr();
			insertRegMemberLhsExpr(pLhsExpr, rdTrs, iInsert);
		}
	}

	string HtInsertRegisterStages::genTrsName(HtDecl * pDecl, int rdTrs, bool bIsCVar)
	{
		// assume name starts with r#_ or c#_ where # is zero or more digits
		//  if c#_ then replace c with r
		//  add $# before _ with # being rdTrs value

		if (rdTrs == 0)
			return pDecl->getName();

		char buf[64];
		sprintf(buf, "$%d", rdTrs);
		string stgStr = buf;

		string name = pDecl->getName();
		if (name[0] == 'c' || name[0] == 'r') {
			int i = 1;
			for ( ; i < name.size() && isdigit(name[i]); i+=1);

			if (i < name.size() && name[i] == '_') {
				name = name.substr(0, i) + stgStr + name.substr(i);
				return name;
			}
		}

		name = (bIsCVar ? "c" : "r") + stgStr + "_" + name;
		return name;
	}

	void HtInsertRegisterStages::walkPostCallback( HtStmtIter & iStmt, HtStmtIter & iInsert, bool isLoa, void * pVoid )
	{
		if (iStmt->getTpSgUrs() < 0)
			return;

		Stmt::StmtClass stmtClass = iStmt->getStmtClass();
		switch (stmtClass) {
		case Stmt::MemberExprClass:
			{
				// process variable
				HtExpr * pExpr = iStmt.asExpr();

				if (isLoa)
					break;

				int rdTrs = pExpr->getTpSgTrs();

				insertRegMemberRhsExpr(pExpr, rdTrs, iInsert);
			}
			break;
		case Stmt::IfStmtClass:
			{
				// handle if statement
				//   first clear all lhs decl minTrs
				//   walk then/else statements and set lhs decl minTrs
				//   while (then or else not empty)
				//     find min lhs expr trs
				//     generate if then/else with min trs

				setIfLhsDeclMinTrs(iStmt);

				bool bLastTrs;
				do {
					int rdTrs = findIfLhsMinTrs(iStmt, bLastTrs);

					HtStmtIter iIfStmt = iStmt;
					if (!bLastTrs)
						dupIfStmtForMinTrs(iStmt, iIfStmt, rdTrs);

					insertRegIfStmt(iIfStmt, rdTrs, iInsert);

				} while (!bLastTrs);
			}
			break;
		case Stmt::CompoundStmtClass:
			break;
		case Stmt::CallExprClass:
			{
				// propagate trs/tpd from inputs to outputs
				HtExpr * pExpr = iStmt.asExpr();

				//propCallExpr( pExpr );
			}
			break;
		case Stmt::BinaryOperatorClass:
			{
				// propagate regStage/subGroup from leaf expr
				HtExpr * pExpr = iStmt.asExpr();
				HtExpr * pLhsExpr = pExpr->getLhs().asExpr();
				HtExpr * pRhsExpr = pExpr->getRhs().asExpr();

				if (pExpr->isAssignStmt()) {
					HtExpr * pBaseExpr = findBaseExpr( pLhsExpr );
					HtDecl * pBaseDecl = pBaseExpr->getMemberDecl();

					if (pBaseDecl->isRegister()) {
						int rdTrs = m_pMethodTpGrp->getSgMaxWrTrs( pLhsExpr->getTpSgId(), pLhsExpr->getTpSgUrs() );

						insertRegMemberRhsExpr(pRhsExpr, rdTrs, iInsert);
					}

				} else {
					assert(pExpr->getTpSgTrs() == pLhsExpr->getTpSgTrs());
					assert(pExpr->getTpSgTrs() == pRhsExpr->getTpSgTrs());
				}
			}
			break;
		case Stmt::ImplicitCastExprClass:
		case Stmt::ParenExprClass:
			{
				// propagate regStage/subGroup from leaf expr
				HtExpr * pExpr = iStmt.asExpr();
				HtExpr * pSubExpr = pExpr->getSubExpr().asExpr();

				assert(pSubExpr->getTpSgUrs() != URS_UNKNOWN);
			}
			break;
		case Stmt::IntegerLiteralClass:
			break;
		default:
			assert(0);
			break;
		}
	}

	void HtInsertRegisterStages::insertRegMemberLhsExpr(HtExpr * pExpr, int rdTrs, HtStmtIter & iInsert)
	{
		assert(pExpr->getStmtClass() == Stmt::MemberExprClass);
		HtExpr * pBaseExpr = findBaseExpr( pExpr );
		HtDecl * pBaseDecl = pBaseExpr->getMemberDecl();

		assert(pExpr->getTpSgTrs() == rdTrs);
		assert(pBaseDecl->getTpSgMinWrTrs() <= rdTrs);

		if (pExpr->getTpSgTrs() == rdTrs)
			return;

		assert(0);
	}

	void HtInsertRegisterStages::insertRegMemberRhsExpr(HtExpr * pExpr, int rdTrs, HtStmtIter & iInsert)
	{
		while (pExpr->getStmtClass() == Stmt::ImplicitCastExprClass)
			pExpr = pExpr->getSubExpr().asExpr();

		assert(pExpr->getStmtClass() == Stmt::MemberExprClass);
		HtExpr * pBaseExpr = findBaseExpr( pExpr );
		HtDecl * pBaseDecl = pBaseExpr->getMemberDecl();

		int wrTrs = pBaseDecl->getTpSgMinWrTrs();

		assert(rdTrs >= wrTrs);
		//assert(wrTrs >= 0);

		if (wrTrs < 0 || rdTrs == wrTrs)
			return;

		// need one or more register stages
		//   create variable name
		//   find or create declaration
		//   replace new declaration in memberExpr

		int declMaxTrs = pBaseDecl->getTpSgMaxRdTrs() >= 0 ?
			pBaseDecl->getTpSgMaxRdTrs() : wrTrs;

		string name = genTrsName(pBaseDecl, rdTrs);
		HtDecl * pTrsDecl = m_pHtDesign->getScModuleDecl()->findSubDecl( name );
		assert(pTrsDecl);

		pBaseExpr->setMemberDecl( pTrsDecl );
	}

	void HtInsertRegisterStages::insertRegDecl(HtDeclList_t & moduleDeclList)
	{
		for (HtDeclIter iDecl(moduleDeclList); !iDecl.isEol(); iDecl++) {
			if (iDecl->getTpSgMinWrTrs() == iDecl->getTpSgMaxRdTrs())
				continue;

			// found a decleration that needs staging
			// first declare c$ variables
			for (int cStgIdx = iDecl->getTpSgMinWrTrs()+1; cStgIdx <= iDecl->getTpSgMaxWrTrs(); cStgIdx += 1) {
				string name = genTrsName( *iDecl, cStgIdx, true);

				HtDecl * pTrsDecl = new HtDecl( Decl::Field, iDecl->getLineInfo() );
				pTrsDecl->setName( name );
				pTrsDecl->setQualType( iDecl->getQualType() );
				pTrsDecl->setDesugaredQualType( iDecl->getDesugaredQualType() );
				pTrsDecl->setTpGrp( iDecl->getTpGrp() );
				pTrsDecl->setTpGrpId( iDecl->getTpGrpId() );
				pTrsDecl->setTpSgId( iDecl->getTpSgId() );
				pTrsDecl->setTpSgUrs( iDecl->getTpSgUrs() );
				pTrsDecl->setTpSgWrTrs( cStgIdx );
				pTrsDecl->setTpSgTpd( TPD_REG_OUT );
				pTrsDecl->setTpSgRdTrs( cStgIdx );
				m_pHtDesign->getScModuleDecl()->addSubDecl( pTrsDecl );
			}

			// now declare r$ variables
			for (int cStgIdx = iDecl->getTpSgMinWrTrs()+1; cStgIdx <= iDecl->getTpSgMaxRdTrs(); cStgIdx += 1) {
				string name = genTrsName( *iDecl, cStgIdx);

				HtDecl * pTrsDecl = new HtDecl( Decl::Field, iDecl->getLineInfo() );
				pTrsDecl->setName( name );
				pTrsDecl->isRegister( iDecl->isRegister() );
				pTrsDecl->setQualType( iDecl->getQualType() );
				pTrsDecl->setDesugaredQualType( iDecl->getDesugaredQualType() );
				pTrsDecl->setTpGrp( iDecl->getTpGrp() );
				pTrsDecl->setTpGrpId( iDecl->getTpGrpId() );
				pTrsDecl->setTpSgId( iDecl->getTpSgId() );
				pTrsDecl->setTpSgUrs( iDecl->getTpSgUrs() );
				pTrsDecl->setTpSgWrTrs( cStgIdx );
				pTrsDecl->setTpSgTpd( TPD_REG_OUT );
				pTrsDecl->setTpSgRdTrs( cStgIdx );
				m_pHtDesign->getScModuleDecl()->addSubDecl( pTrsDecl );
			}
		}
	}

	void HtInsertRegisterStages::insertRegAssign(HtDeclList_t & moduleDeclList, HtStmtList & methodStmtList)
	{
		HtStmtIter iInsert ( methodStmtList );
		HtStmtIter iInsertEnd = iInsert.eol();

		for (HtDeclIter iDecl(moduleDeclList); !iDecl.isEol(); iDecl++) {
			if (iDecl->getTpSgMinWrTrs() == iDecl->getTpSgMaxRdTrs())
				continue;

			// found a decleration that needs staging
			for (int rStgIdx = iDecl->getTpSgMinWrTrs()+1; rStgIdx <= iDecl->getTpSgMaxRdTrs(); rStgIdx += 1) {

				// insert c_ assignments at beginning of module statement list
				if (rStgIdx <= iDecl->getTpSgMaxWrTrs()) {

					string rhsName = genTrsName( *iDecl, rStgIdx);
					string lhsName = genTrsName( *iDecl, rStgIdx, true);

					HtDecl * pLhsDecl = m_pHtDesign->getScModuleDecl()->findSubDecl( lhsName );
					HtDecl * pRhsDecl = m_pHtDesign->getScModuleDecl()->findSubDecl( rhsName );

					HtExpr * pHtLhs = new HtExpr( Stmt::MemberExprClass, pLhsDecl->getQualType(), pRhsDecl->getLineInfo() );
					pHtLhs->setMemberDecl( pLhsDecl );

					HtExpr * pHtRhs = new HtExpr( Stmt::MemberExprClass, pRhsDecl->getQualType(), pRhsDecl->getLineInfo() );
					pHtRhs->setMemberDecl( pRhsDecl );

					HtExpr * pThis = new HtExpr( Stmt::CXXThisExprClass, HtQualType( 0 ), pRhsDecl->getLineInfo() );
					pHtLhs->setBase( pThis );
					pHtRhs->setBase( pThis );

					HtDesign::genAssignStmts(iInsert, pHtLhs, pHtRhs);
				}

				// now insert register assignment statement at end of module statement list
				{
					string lhsName = genTrsName( *iDecl, rStgIdx);

					string rhsName;
					if (rStgIdx <= iDecl->getTpSgMaxWrTrs())
						rhsName = genTrsName( *iDecl, rStgIdx-1, true );
					else
						rhsName = genTrsName( *iDecl, rStgIdx-1 );

					HtDecl * pTrsDecl = m_pHtDesign->getScModuleDecl()->findSubDecl( lhsName );
					HtDecl * pTrsM1Decl = m_pHtDesign->getScModuleDecl()->findSubDecl( rhsName );

					HtExpr * pHtLhs = new HtExpr( Stmt::MemberExprClass, pTrsDecl->getQualType(), pTrsM1Decl->getLineInfo() );
					pHtLhs->setMemberDecl( pTrsDecl );

					HtExpr * pHtRhs = new HtExpr( Stmt::MemberExprClass, pTrsM1Decl->getQualType(), pTrsM1Decl->getLineInfo() );
					pHtRhs->setMemberDecl( pTrsM1Decl );

					HtExpr * pThis = new HtExpr( Stmt::CXXThisExprClass, HtQualType( 0 ), pTrsM1Decl->getLineInfo() );
					pHtLhs->setBase( pThis );
					pHtRhs->setBase( pThis );

					HtStmtIter iSave = iInsertEnd-1;
					HtDesign::genAssignStmts(iInsertEnd, pHtLhs, pHtRhs);
					iInsertEnd = iSave+1;
				}
			}
		}
	}

	HtExpr * HtInsertRegisterStages::findBaseExpr( HtExpr * pExpr )
	{
		// find the base declaration for the reference
		HtExpr * pBaseExpr = 0;
		for (;;) {
			Stmt::StmtClass stmtClass = pExpr->getStmtClass();
			switch (stmtClass) {
			case Stmt::MemberExprClass:
				pBaseExpr = pExpr;
				pExpr = pExpr->getBase().asExpr();
				break;
			case Stmt::ImplicitCastExprClass:
			case Stmt::CXXStaticCastExprClass:
				pExpr = pExpr->getSubExpr().asExpr();
				break;
			case Stmt::CXXThisExprClass:
				return pBaseExpr;
			default:
				assert(0);
			}
		}
		return 0;
	}

	HtDecl * HtInsertRegisterStages::findBaseDecl( HtExpr * pExpr )
	{
		// find the base declaration for the reference
		HtExpr * pBaseExpr = findBaseExpr( pExpr );
		HtDecl * pBaseDecl = pBaseExpr == 0 ? 0 : pBaseExpr->getMemberDecl();

		assert(pBaseDecl == 0 || pBaseDecl->getKind() == Decl::Field);
		return pBaseDecl;
	}
}


text:
(function (angular) {
    angular
        .module('mediaCenterContent')
        .directive("loadImage", [function () {
            return {
                restrict: 'A',
                link: function (scope, element, attrs) {
                    element.attr("src", "../../../../styles/media/holder-" + attrs.loadImage + ".gif");

                    var elem = $("<img>");
                    elem[0].onload = function () {
                        element.attr("src", attrs.finalSrc);
                        elem.remove();
                    };
                    elem.attr("src", attrs.finalSrc);
                }
            };
        }]);
})(window.angular);

redpajama_set_name: RedPajamaGithub


text:
import axios from 'axios'
// ------------------------------------
// Constants
// ------------------------------------
export const EVENTS_LOADED = 'EVENTS_LOADED'
// ------------------------------------
// Actions
// ------------------------------------
export function eventsLoaded (events) {
  return {
    type: EVENTS_LOADED,
    payload:events
  }
}

function transformData (arr) {
  return arr.map(function (event) {
    event.start = new Date(event.start)
    event.end = new Date(event.end)
    return event
  })
}

export const loadEvents = (date) => {
  return (dispatch, getstate) => {
    return axios.post('http://localhost:3001/api/calendar', { Date:date })
        .then(response => dispatch(eventsLoaded(transformData(response.data))))
  }
}

export const actions = {
  loadEvents
}

// ------------------------------------
// Action Handlers
// ------------------------------------

const ACTION_HANDLERS = {
  [EVENTS_LOADED] : (state, action) =>
  Object.assign({}, { 'events': getNewEvents(state.events, action.payload) })
}
function getNewEvents (currentEvents, newEvents) {
  if (currentEvents.length === 0) {
    return newEvents
  }
  if (newEvents.length === 0) {
    return currentEvents
  }
  var forAdding = newEvents.filter((item) => {
    return currentEvents.map((ev) => ev.id).indexOf(item.id) === -1
  })
  if (forAdding === null || forAdding === undefined) {
    currentEvents
  }
  return currentEvents.concat(forAdding)
}

// ------------------------------------
// Reducer
// ------------------------------------
const initialState = { events: [] }
export default function CalendarReducer (state = initialState, action) {
  const handler = ACTION_HANDLERS[action.type]
  return handler ? handler(state, action) : state
}


text:
layout: post
title:  "Devoxx France 2015"
date:   2015-04-14
categories: blog devoxx
---

Last week I was at [Devoxx France 2015](http://www.devoxx.fr/). First time for me!

# Great people

I would recommand anyone attend to this kind of conference, where you find a bunch of interesting people, from France and abroad.
For instance I had the chance to meet gopher [@francesc](https://twitter.com/francesc) and asking him a ton of questions about Golang, Kubernetes and other stuff around Google.

# Great conference

This was a really a great conference, great organization and everything needed to have a good feeling that we are part of something special. And a great community as well.

# Great presentations (some less)

This is a special part. As anyone I guess, on [friday morning](http://cfp.devoxx.fr/2015/byday/fri), the keynotes were just awesome! I am really thankful to the devoxx team!

That said, I also attended other presentations which were not as great: presentations just mixing a lot of buzzwords and taking assumptions I would not make myself. And the [KISS principle](http://en.wikipedia.org/wiki/KISS_principle) ?

# New directions to take

And now, I have to take actions:

* use [spring boot actuator](http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#production-ready)
* enjoying [monoids](http://en.wikipedia.org/wiki/Monoid) in my code
* investigating more on [Docker](https://www.docker.com/)


text:
package org.apache.activemq.security;

import java.net.URI;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.jms.Connection;
import javax.jms.JMSException;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.JmsTestSupport;
import org.apache.activemq.broker.BrokerFactory;
import org.apache.activemq.broker.BrokerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The configuration is set to except a maximum of 2 concurrent connections
 * As the exception is deliberately ignored, the ActiveMQConnection would continue to
 * attempt to connect unless the connection's transport was also stopped on an error.
 * <br>
 * As the maximum connections allowed is 2, no more connections would be allowed unless
 * the transport was adequately destroyed on the broker side.
 */

public class DoSTest extends JmsTestSupport {

   private static final Logger LOG = LoggerFactory.getLogger(DoSTest.class);

   public void testInvalidAuthentication() throws Throwable {

      // with failover reconnect, we don't expect this thread to complete
      // but periodically the failure changes from ExceededMaximumConnectionsException on the broker
      // side to a SecurityException.
      // A failed to authenticated but idle connection (dos style) is aborted by the inactivity monitor
      // since useKeepAlive=false

      final AtomicBoolean done = new AtomicBoolean(false);
      Thread thread = new Thread() {
         Connection connection = null;

         @Override
         public void run() {
            for (int i = 0; i < 1000 && !done.get(); i++) {
               ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
               try {
                  // Bad password
                  connection = factory.createConnection("bad", "krap");
                  connection.start();
                  fail("Expected exception.");
               }
               catch (JMSException e) {
                  // ignore exception and don't close
                  e.printStackTrace();
               }
            }
         }
      };

      thread.start();

      // run dos for a while
      TimeUnit.SECONDS.sleep(10);

      LOG.info("trying genuine connection ...");
      // verify a valid connection can work with one of the 2 allowed connections provided it is eager!
      // it could take a while as it is competing with the three other reconnect threads.
      // wonder if it makes sense to serialise these reconnect attempts on an executor
      ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("failover:(tcp://127.0.0.1:61616)?useExponentialBackOff=false&reconnectDelay=10");
      Connection goodConnection = factory.createConnection("user", "password");
      goodConnection.start();
      goodConnection.close();

      LOG.info("giving up on DOS");
      done.set(true);
   }

   @Override
   protected BrokerService createBroker() throws Exception {
      return createBroker("org/apache/activemq/security/dos-broker.xml");
   }

   protected BrokerService createBroker(String uri) throws Exception {
      LOG.info("Loading broker configuration from the classpath with URI: " + uri);
      return BrokerFactory.createBroker(new URI("xbean:" + uri));
   }

}


text:
from django.http import JsonResponse, HttpResponse
import gspread
from oauth2client.service_account import ServiceAccountCredentials
import json
from django.conf import settings

def index(request):
    return HttpResponse('
Welcome Message
')

def getAllData(request, file_name):
    print request
    FILE_NAME = file_name # file name on google drive

    scope = ['https://spreadsheets.google.com/feeds']
    creds = ServiceAccountCredentials.from_json_keyfile_name('spreadsheet/credentials/client_secret.json', scope)
    client = gspread.authorize(creds)

    sheet = client.open(FILE_NAME).sheet1
    data = sheet.get_all_records()

    return JsonResponse(data, safe=False)


text:
var config = require('../config')
var opn = require('opn')
var path = require('path')
var express = require('express')
var webpack = require('webpack')
var webpackConfig = require('./webpack.dev.conf')
if (!process.env.NODE_ENV) {
  process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
}

// default port where dev server listens for incoming traffic
var port = process.env.PORT || config.dev.port
// automatically open browser, if not set will be false
var autoOpenBrowser = !!config.dev.autoOpenBrowser
var app = express()

var compiler = webpack(webpackConfig)

var devMiddleware = require('webpack-dev-middleware')(compiler, {
  publicPath: webpackConfig.output.publicPath,
  quiet: true
})

var hotMiddleware = require('webpack-hot-middleware')(compiler, {
  log: () => {}
})
// force page reload when html-webpack-plugin template changes
compiler.plugin('compilation', function (compilation) {
  compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
    hotMiddleware.publish({ action: 'reload' })
    cb()
  })
})

// serve webpack bundle output
app.use(devMiddleware)

// enable hot-reload and state-preserving
// compilation error display
app.use(hotMiddleware)

// serve pure static assets
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
app.use(staticPath, express.static('./static'))

var uri = 'http://localhost:' + port

var _resolve
var readyPromise = new Promise(resolve => {
  _resolve = resolve
})

console.log('> Starting dev server...')
devMiddleware.waitUntilValid(() => {
  console.log('> Listening at ' + uri + '\n')
  if (autoOpenBrowser) {
    opn(uri)
  }
  _resolve()
})

var server = app.listen(port)

module.exports = {
  ready: readyPromise,
  close: () => {
    server.close()
  }
}


text:
#import "SWGProfile.h"

@implementation SWGProfile

/**
 * Maps json key to property name.
 * This method is used by `JSONModel`.
 */
+ (JSONKeyMapper *)keyMapper
{
  return [[JSONKeyMapper alloc] initWithDictionary:@{ @"first_name": @"firstName", @"last_name": @"lastName", @"email": @"email", @"picture": @"picture", @"promo_code": @"promoCode" }];
}

/**
 * Indicates whether the property with the given name is optional.
 * If `propertyName` is optional, then return `YES`, otherwise return `NO`.
 * This method is used by `JSONModel`.
 */
+ (BOOL)propertyIsOptional:(NSString *)propertyName
{
  NSArray *optionalProperties = @[@"firstName", @"lastName", @"email", @"picture", @"promoCode"];

  if ([optionalProperties containsObject:propertyName]) {
    return YES;
  }
  else {
    return NO;
  }
}

/**
 * Gets the string presentation of the object.
 * This method will be called when logging model object using `NSLog`.
 */
- (NSString *)description {
    return [[self toDictionary] description];
}

@end


text:
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">

    <title>PHPXRef 0.7.1 : Unnamed Project : Detail view of MY_Model.php</title>
    <link rel="stylesheet" href="../../sample.css" type="text/css">
    <link rel="stylesheet" href="../../sample-print.css" type="text/css" media="print">

    <meta http-equiv="content-type" content="text/html;charset=iso-8859-1">

            [ Index ]

PHP Cross Reference of Unnamed Project

[ Show Explorer ]
[ Hide Navbar ]

title

Body

[close]

/application/core/ -> MY_Model.php (summary)

[Source view]
[Print]
[Project Stats]

Bonfire An open source project to allow developers get a jumpstart their development of CodeIgniter applications

Author: 	Bonfire Dev Team

Copyright: 	Copyright (c) 2011 - 2013, Bonfire Dev Team

License: 	http://cibonfire.com/docs/guides/license.html

File Size: 	1880 lines (52 kb)

Included or required:	0 times

Referenced: 	0 times

Includes or requires: 	0 files

Defines 2 classes

BF_Model:: (72 methods):

  __construct()

  find()

  find_all()

  find_all_by()

  find_by()

  insert()

  insert_batch()

  update()

  update_where()

  update_batch()

  delete()

  delete_where()

  is_unique()

  count_all()

  count_by()

  get_field()

  format_dropdown()

  where()

  order_by()

  soft_delete()

  as_array()

  as_object()

  as_json()

  return_insert_id()

  skip_validation()

  created_on()

  modified_on()

  trigger()

  get_validation_rules()

  validate()

  protect_attributes()

  set_date()

  _return_type()

  get_db_error_message()

  set_table()

  get_table()

  get_key()

  get_created_by_field()

  get_created_field()

  get_deleted_field()

  get_deleted_by_field()

  get_field_info()

  get_modified_by_field()

  get_modified_field()

  set_date_format()

  set_modified()

  set_soft_deletes()

  logit()

  prep_data()

  select()

  select_max()

  select_min()

  select_avg()

  select_sum()

  distinct()

  from()

  join()

  or_where()

  where_in()

  or_where_in()

  where_not_in()

  or_where_not_in()

  like()

  not_like()

  or_like()

  or_not_like()

  group_by()

  having()

  or_having()

  limit()

  offset()

  set()

MY_Model:: (0 methods):

Class: BF_Model  - X-Ref

Bonfire Base Model

The Base model implements standard CRUD functions that can be

used and overriden by module models. This helps to maintain

a standard interface to program to, and makes module creation

faster.

__construct()
X-Ref

BF_Model's constructor

Setup the DB connection if it doesn't exist,

setup the before_insert and before_update events

return: void

find($id='')
X-Ref

Searches for a single row in the database.

param: string $id The primary key of the record to search for.

return: mixed An object/array representing the db row, or FALSE.

find_all()
X-Ref

Returns all records in the table.

By default, there is no 'where' clause, but you can filter

the results that are returned by using either CodeIgniter's

Active Record functions before calling this function, or

through method chaining with the where() method of this class.

return: mixed An array of objects/arrays representing the results, or FALSE on failure or empty set.

find_all_by($field=NULL, $value=NULL, $type='and')
X-Ref

A convenience method that combines a where() and find_all() call into a single call.

param: mixed  $field The table field to search in.

param: mixed  $value The value that field should be.

param: string $type  The type of where clause to create. Either 'and' or 'or'.

return: bool|mixed An array of objects representing the results, or FALSE on failure or empty set.

find_by($field='', $value='', $type='and')
X-Ref

Returns the first result that matches the field/values passed.

param: string $field Either a string or an array of fields to match against. If an array is passed it, the $value parameter is ignored since the array is expected to have key/value pairs in it.

param: string $value The value to match on the $field. Only used when $field is a string.

param: string $type  The type of where clause to create. Either 'and' or 'or'.

return: bool|mixed An object representing the first result returned.

insert($data=null)
X-Ref

Inserts a row of data into the database.

param: array $data an array of key/value pairs to insert.

return: bool|mixed Either the $id of the row inserted, or FALSE on failure.

insert_batch($data=null)
X-Ref

Inserts a batch of data into the database.

param: array $data an array of key/value pairs to insert.

return: bool|mixed Either the $id of the row inserted, or FALSE on failure.

update($where=NULL, $data=NULL)
X-Ref

Updates an existing row in the database.

param: mixed    $where    The primary_key value of the row to update or the where clause.

param: array $data    An array of key/value pairs to update.

return: bool TRUE/FALSE

update_where($field=NULL, $value=NULL, $data=NULL)
X-Ref

A convenience method that allows you to use any field/value pair as the 'where' portion of your update.

param: string $field The field to match on.

param: string $value The value to search the $field for.

param: array  $data  An array of key/value pairs to update.

return: bool TRUE/FALSE

update_batch($data = NULL, $index = NULL)
X-Ref

Updates a batch of existing rows in the database.

param: array  $data  An array of key/value pairs to update.

param: string $index A string value of the db column to use as the where key

return: bool TRUE/FALSE

delete($id=NULL)
X-Ref

Performs a delete on the record specified. If $this->soft_deletes is TRUE,

it will attempt to set $this->deleted_field on the current record

to '1', to allow the data to remain in the database.

param: mixed $id The primary_key value to match against.

return: bool TRUE/FALSE

delete_where($where=NULL)
X-Ref

Performs a delete using any field/value pair(s) as the 'where'

portion of your delete statement. If $this->soft_deletes is

TRUE, it will attempt to set $this->deleted_field on the current

record to '1', to allow the data to remain in the database.

param: mixed/array $data key/value pairs accepts an associative array or a string

return: bool TRUE/FALSE

is_unique($field='', $value='')
X-Ref

Checks whether a field/value pair exists within the table.

param: string $field The field to search for.

param: string $value The value to match $field against.

return: bool TRUE/FALSE

count_all()
X-Ref

Returns the number of rows in the table.

return: int

count_by($field='', $value=NULL)
X-Ref

Returns the number of elements that match the field/value pair.

param: string $field The field to search for.

param: string $value The value to match $field against.

return: bool|int

get_field($id=NULL, $field='')
X-Ref

A convenience method to return only a single field of the specified row.

param: mixed  $id    The primary_key value to match against.

param: string $field The field to search for.

return: bool|mixed The value of the field.

format_dropdown()
X-Ref

A convenience method to return options for form dropdown menus.

Can pass either Key ID and Label Table names or Just Label Table name.

return: array The options for the dropdown.

where($field=NULL, $value=NULL)
X-Ref

Sets the where portion of the query in a chainable format.

param: mixed  $field The field to search the db on. Can be either a string with the field name to search, or an associative array of key/value pairs.

param: string $value The value to match the field against. If $field is an array, this value is ignored.

return: BF_Model An instance of this class.

order_by($field=NULL, $order='asc')
X-Ref

Inserts a chainable order_by method from either a string or an

array of field/order combinations. If the $field value is an array,

it should look like:

array(

'field1' => 'asc',

'field2' => 'desc'

);

param: mixed  $field The field to order the results by, or an array of field/order pairs.

param: string $order Which direction to order the results ('asc' or 'desc')

return: BF_Model An instance of this class.

soft_delete($val=TRUE)
X-Ref

Sets the value of the soft deletes flag.

<code>

$this->my_model->soft_delete(true)->delete($id);

</code>

param: boolean $val If TRUE, will temporarily use soft_deletes.

return: BF_Model     An instance of this class.

as_array()
X-Ref

Temporarily sets our return type to an array.

as_object()
X-Ref

Temporarily sets our return type to an object.

as_json()
X-Ref

Temporarily sets our object return to a json object.

return_insert_id($return=true)
X-Ref

Sets the value of the return_insert_id flag

param: Bool $return (optional) whether insert will return the ID

return: Object    returns $this to allow method chaining

skip_validation($skip=true)
X-Ref

Sets the value of the skip_validation flag

param: Bool $skip (optional) whether to skip validation in the model

return: Object    returns $this to allow method chaining

created_on($row)
X-Ref

Sets the created on date for the object based on the

current date/time and date_format. Will not overwrite existing.

param: array  $row  The array of data to be inserted

return: array

modified_on($row)
X-Ref

Sets the modified_on date for the object based on the

current date/time and date_format. Will not overwrite existing.

param: array  $row  The array of data to be inserted

return: array

trigger($event, $data=false)
X-Ref

Triggers a model-specific event and call each of it's observers.

param: string     $event     The name of the event to trigger

param: mixed     $data     The data to be passed to the callback functions.

return: mixed

get_validation_rules($type='update')
X-Ref

Get the validation rules for the model

param: String $type Either 'update' or 'insert', appends rules set in $insert_validation_rules on insert

return: array    The validation rules for the model or an empty array

validate($data, $type='update')
X-Ref

Validates the data passed into it based upon the form_validation rules

setup in the $this->validation_rules property.

If $type == 'insert', any additional rules in the class var $insert_validation_rules

for that field will be added to the rules.

param: array $data      An array of data to validate

param: string $type     Either 'update' or 'insert'.

return: array/bool       The original data or FALSE

protect_attributes($row)
X-Ref

Protect attributes by removing them from $row array. Useful for

removing id, or submit buttons names if you simply throw your $_POST

array at your model. :)

param: object/array $row The value pair item to remove.

set_date($user_date=NULL)
X-Ref

A utility function to allow child models to use the type of

date/time format that they prefer. This is primarily used for

setting created_on and modified_on values, but can be used by

inheriting classes.

The available time formats are:

* 'int'        - Stores the date as an integer timestamp.

* 'datetime'    - Stores the date and time in the SQL datetime format.

* 'date'        - Stores teh date (only) in the SQL date format.

param: mixed $user_date An optional PHP timestamp to be converted.

return: int|null|string The current/user time converted to the proper format.

_return_type($multi = FALSE)
X-Ref

Return the method name for the current return type

get_db_error_message()
X-Ref

Allows you to retrieve error messages from the database

return: string

set_table($table='')
X-Ref

Allows you to set the table to use for all methods during runtime.

param: string $table The table name to use (do not include the prefix!)

return: void

get_table()
X-Ref

Allows you to get the table name

return: string $this->table_name (current model table name)

get_key()
X-Ref

Allows you to get the table primary key

return: string $this->key (current model table primary key)

get_created_by_field()
X-Ref

Get the name of the created by field

return: String    The name of the field or an empty string

get_created_field()
X-Ref

Get the name of the created field

return: String    The name of the field or an empty string

get_deleted_field()
X-Ref

Get the name of the deleted field

return: String    The name of the field if soft_deletes is enabled, else an empty string

get_deleted_by_field()
X-Ref

Get the name of the deleted by field

return: String    The name of the field or an empty string

get_field_info()
X-Ref

Get the metadata for the model's database fields

Returns the model's database field metadata stored in $this->field_info

if set, else it tries to retrieve the metadata from

$this->db->field_data($this->table_name);

return: array    Returns the database field metadata for this model

get_modified_by_field()
X-Ref

Get the name of the modified by field

return: String    The name of the field or an empty string

get_modified_field()
X-Ref

Get the name of the modified field

return: String    The name of the field or an empty string

set_date_format($format='int')
X-Ref

Sets the date_format to use for setting created_on and modified_on values.

param: string $format String describing format. Valid values are: 'int', 'datetime', 'date'

return: bool

set_modified($modified=TRUE)
X-Ref

Sets whether to auto-create modified_on dates in the update method.

param: bool $modified

return: bool

set_soft_deletes($soft=TRUE)
X-Ref

Sets whether soft deletes are used by the delete method.

param: bool $soft

return: bool

logit($message='', $level='debug')
X-Ref

Logs an error to the Console (if loaded) and to the log files.

param: string $message The string to write to the logs.

param: string $level   The log level, as per CI log_message method.

return: mixed

prep_data($post_data)
X-Ref

Extracts the model's fields (except the key and those handled by

Observers) from the $post_data and returns an array of name => value pairs

param: Array $post_data The post data, usually $this->input->post() when called from the controller

return: Array    An array of name => value pairs containing the data for the model's fields

select($select = '*', $escape = NULL)
X-Ref

No description

select_max($select = '', $alias = '')
X-Ref

No description

select_min($select = '', $alias = '')
X-Ref

No description

select_avg($select = '', $alias = '')
X-Ref

No description

select_sum($select = '', $alias = '')
X-Ref

No description

distinct($val=TRUE)
X-Ref

No description

from($from)
X-Ref

No description

join($table, $cond, $type = '')
X-Ref

No description

or_where($key, $value = NULL, $escape = TRUE)
X-Ref

No description

where_in($key = NULL, $values = NULL)
X-Ref

No description

or_where_in($key = NULL, $values = NULL)
X-Ref

No description

where_not_in($key = NULL, $values = NULL)
X-Ref

No description

or_where_not_in($key = NULL, $values = NULL)
X-Ref

No description

like($field, $match = '', $side = 'both')
X-Ref

No description

not_like($field, $match = '', $side = 'both')
X-Ref

No description

or_like($field, $match = '', $side = 'both')
X-Ref

No description

or_not_like($field, $match = '', $side = 'both')
X-Ref

No description

group_by($by)
X-Ref

No description

having($key, $value = '', $escape = TRUE)
X-Ref

No description

or_having($key, $value = '', $escape = TRUE)
X-Ref

No description

limit($value, $offset = '')
X-Ref

No description

offset($offset)
X-Ref

No description

set($key, $value = '', $escape = TRUE)
X-Ref

No description

Class: MY_Model  - X-Ref

MY_Model

This simply extends BF_Model for backwards compatibility,

and to provide a placeholder class that your project can customize

extend as needed.

Generated: Thu Oct 23 19:15:14 2014
	Cross-referenced by PHPXref 0.7.1


text:
<?php

namespace conquer\proxypool\controllers;

use Yii;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use conquer\proxypool\models\Fineproxy;
use yii\data\ActiveDataProvider;

/**
 * FineproxyController implements the CRUD actions for Fineproxy model.
 */
class FineproxyController extends Controller
{
    public function behaviors()
    {
        return [
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'delete' => ['post'],
                ],
            ],
        ];
    }

    /**
     * Lists all Fineproxy models.
     * @return mixed
     */
    public function actionIndex()
    {
        $dataProvider = new ActiveDataProvider([
            'query' => Fineproxy::find(),
        ]);

        return $this->render('index', [
            'dataProvider' => $dataProvider,
        ]);
    }

    /**
     * Displays a single Fineproxy model.
     * @param integer $id
     * @return mixed
     */
    public function actionView($id)
    {
        if(Yii::$app->request->isAjax)
            return $this->renderAjax('view', [
                'model' => $this->findModel($id),
            ]);
        else
            return $this->render('view', [
                'model' => $this->findModel($id),
            ]);
    }

    /**
     * Creates a new Fineproxy model.
     * If creation is successful, the browser will be redirected to the 'view' page.
     * @return mixed
     */
    public function actionCreate()
    {
        $model = new Fineproxy();

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            if(Yii::$app->request->isAjax)
                return $this->redirect(['index']);
            else
                return $this->redirect(['view', 'id' => $model->fineproxy_id]);
        } else {
            if(Yii::$app->request->isAjax)
                return $this->renderAjax('create', [
                    'model' => $model,
                ]);
            else
                return $this->render('create', [
                    'model' => $model,
                ]);
        }
    }

    /**
     * Updates an existing Fineproxy model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id
     * @return mixed
     */
    public function actionUpdate($id)
    {
        $model = $this->findModel($id);

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            if(Yii::$app->request->isAjax)
                return $this->redirect(['index']);
            else
                return $this->redirect(['view', 'id' => $model->fineproxy_id]);
        } else {
            if(Yii::$app->request->isAjax)
                return $this->renderAjax('update', [
                    'model' => $model,
                ]);
            else
                return $this->render('update', [
                    'model' => $model,
                ]);
        }
    }

    /**
     * Deletes an existing Fineproxy model.
     * If deletion is successful, the browser will be redirected to the 'index' page.
     * @param integer $id
     * @return mixed
     */
    public function actionDelete($id)
    {
        $this->findModel($id)->delete();

        return $this->redirect(['index']);
    }

    /**
     * Finds the Fineproxy model based on its primary key value.
     * If the model is not found, a 404 HTTP exception will be thrown.
     * @param integer $id
     * @return Fineproxy the loaded model
     * @throws NotFoundHttpException if the model cannot be found
     */
    protected function findModel($id)
    {
        if (($model = Fineproxy::findOne($id)) !== null) {
            return $model;
        } else {
            throw new NotFoundHttpException('The requested page does not exist.');
        }
    }
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<cruisecontrol>
<checkstyle version="1.2.0RC3">
  <file name="/opt/cruisecontrol/projects/phpcb/source/src/JSGenerator.php">
    <error line="37" column="1" severity="error" message="@category tag comment indented incorrectly. Expected 2 spaces but found 3." source="PEAR.Commenting.FileCommentSniff"/>
    <error line="38" column="1" severity="error" message="@package tag comment indented incorrectly. Expected 3 spaces but found 4." source="PEAR.Commenting.FileCommentSniff"/>
    <error line="39" column="1" severity="error" message="@author tag comment indented incorrectly. Expected 4 spaces but found 5." source="PEAR.Commenting.FileCommentSniff"/>
    <error line="40" column="1" severity="error" message="@copyright tag comment indented incorrectly. Expected 1 spaces but found 2." source="PEAR.Commenting.FileCommentSniff"/>
    <error line="41" column="1" severity="error" message="@license tag comment indented incorrectly. Expected 3 spaces but found 4." source="PEAR.Commenting.FileCommentSniff"/>
    <error line="42" column="1" severity="error" message="@version tag comment indented incorrectly. Expected 3 spaces but found 4." source="PEAR.Commenting.FileCommentSniff"/>
    <error line="43" column="1" severity="error" message="@link tag comment indented incorrectly. Expected 6 spaces but found 7." source="PEAR.Commenting.FileCommentSniff"/>
    <error line="44" column="1" severity="error" message="@since tag comment indented incorrectly. Expected 5 spaces but found 6." source="PEAR.Commenting.FileCommentSniff"/>
    <error line="45" column="1" severity="warning" message="PHP version not specified" source="PEAR.Commenting.FileCommentSniff"/>
    <error line="50" column="1" severity="error" message="@category tag comment indented incorrectly. Expected 2 spaces but found 3." source="PEAR.Commenting.ClassCommentSniff"/>
    <error line="51" column="1" severity="error" message="@package tag comment indented incorrectly. Expected 3 spaces but found 4." source="PEAR.Commenting.ClassCommentSniff"/>
    <error line="52" column="1" severity="error" message="@author tag comment indented incorrectly. Expected 4 spaces but found 5." source="PEAR.Commenting.ClassCommentSniff"/>
    <error line="53" column="1" severity="error" message="@author tag comment indented incorrectly. Expected 4 spaces but found 5." source="PEAR.Commenting.ClassCommentSniff"/>
    <error line="54" column="1" severity="error" message="@copyright tag comment indented incorrectly. Expected 1 spaces but found 2." source="PEAR.Commenting.ClassCommentSniff"/>
    <error line="55" column="1" severity="error" message="@license tag comment indented incorrectly. Expected 3 spaces but found 4." source="PEAR.Commenting.ClassCommentSniff"/>
    <error line="56" column="1" severity="error" message="@version tag comment indented incorrectly. Expected 3 spaces but found 4." source="PEAR.Commenting.ClassCommentSniff"/>
    <error line="57" column="1" severity="error" message="@link tag comment indented incorrectly. Expected 6 spaces but found 7." source="PEAR.Commenting.ClassCommentSniff"/>
    <error line="58" column="1" severity="error" message="@since tag comment indented incorrectly. Expected 5 spaces but found 6." source="PEAR.Commenting.ClassCommentSniff"/>
    <error line="60" column="1" severity="error" message="Class name must begin with a capital letter" source="PEAR.NamingConventions.ValidClassNameSniff"/>
    <error line="67" column="13" severity="error" message="Private member variable "cbFDHandler" must be prefixed with an underscore" source="PEAR.NamingConventions.ValidVariableNameSniff"/>
    <error line="107" column="1" severity="error" message="Doc comment for "$projectSource" missing" source="PEAR.Commenting.FunctionCommentSniff"/>
    <error line="123" column="21" severity="error" message="Opening parenthesis of a multi-line function call must be the last content on the line" source="PEAR.Functions.FunctionCallSignatureSniff"/>
    <error line="123" column="95" severity="warning" message="Line exceeds 85 characters; contains 95 characters" source="PEAR.Files.LineLengthSniff"/>
    <error line="124" column="1" severity="error" message="Multi-line function call not indented correctly; expected 12 spaces but found 32" source="PEAR.Functions.FunctionCallSignatureSniff"/>
    <error line="125" column="1" severity="error" message="Multi-line function call not indented correctly; expected 8 spaces but found 32" source="PEAR.Functions.FunctionCallSignatureSniff"/>
    <error line="125" column="56" severity="error" message="Closing parenthesis of a multi-line function call must be on a line by itself" source="PEAR.Functions.FunctionCallSignatureSniff"/>
    <error line="151" column="21" severity="error" message="Line indented incorrectly; expected 16 spaces, found 20" source="PEAR.WhiteSpace.ScopeIndentSniff"/>
    <error line="154" column="21" severity="error" message="Line indented incorrectly; expected 16 spaces, found 20" source="PEAR.WhiteSpace.ScopeIndentSniff"/>
    <error line="157" column="21" severity="error" message="Line indented incorrectly; expected 16 spaces, found 20" source="PEAR.WhiteSpace.ScopeIndentSniff"/>
    <error line="160" column="21" severity="error" message="Line indented incorrectly; expected 16 spaces, found 20" source="PEAR.WhiteSpace.ScopeIndentSniff"/>
    <error line="197" column="35" severity="error" message="Opening parenthesis of a multi-line function call must be the last content on the line" source="PEAR.Functions.FunctionCallSignatureSniff"/>
    <error line="198" column="1" severity="error" message="Multi-line function call not indented correctly; expected 28 spaces but found 42" source="PEAR.Functions.FunctionCallSignatureSniff"/>
    <error line="199" column="1" severity="error" message="Multi-line function call not indented correctly; expected 28 spaces but found 42" source="PEAR.Functions.FunctionCallSignatureSniff"/>
    <error line="200" column="1" severity="error" message="Multi-line function call not indented correctly; expected 24 spaces but found 42" source="PEAR.Functions.FunctionCallSignatureSniff"/>
    <error line="200" column="94" severity="error" message="Closing parenthesis of a multi-line function call must be on a line by itself" source="PEAR.Functions.FunctionCallSignatureSniff"/>
    <error line="200" column="96" severity="warning" message="Line exceeds 85 characters; contains 95 characters" source="PEAR.Files.LineLengthSniff"/>
    <error line="207" column="46" severity="error" message="There must be a single space between the closing parenthesis and the openning brace of a multi-line IF statement" source="PEAR.ControlStructures.MultiLineConditionSniff"/>
    <error line="207" column="13" severity="warning" message="Inline control structures are discouraged" source="PEAR.ControlStructures.InlineControlStructureSniff"/>
    <error line="208" column="18" severity="error" message="Opening parenthesis of a multi-line function call must be the last content on the line" source="PEAR.Functions.FunctionCallSignatureSniff"/>
    <error line="208" column="112" severity="warning" message="Line exceeds 85 characters; contains 112 characters" source="PEAR.Files.LineLengthSniff"/>
    <error line="209" column="1" severity="error" message="Multi-line function call not indented correctly; expected 12 spaces but found 25" source="PEAR.Functions.FunctionCallSignatureSniff"/>
    <error line="209" column="105" severity="error" message="Closing parenthesis of a multi-line function call must be on a line by itself" source="PEAR.Functions.FunctionCallSignatureSniff"/>
    <error line="209" column="107" severity="warning" message="Line exceeds 85 characters; contains 106 characters" source="PEAR.Files.LineLengthSniff"/>
    <error line="222" column="1" severity="error" message="Doc comment for "$errors" missing" source="PEAR.Commenting.FunctionCommentSniff"/>
    <error line="226" column="13" severity="error" message="Private method name "cbJSGenerator::echoJSTreeNodes" must be prefixed with an underscore" source="PEAR.NamingConventions.ValidFunctionNameSniff"/>
    <error line="235" column="24" severity="error" message="Opening parenthesis of a multi-line function call must be the last content on the line" source="PEAR.Functions.FunctionCallSignatureSniff"/>
    <error line="235" column="108" severity="warning" message="Line exceeds 85 characters; contains 108 characters" source="PEAR.Files.LineLengthSniff"/>
    <error line="236" column="1" severity="error" message="Multi-line function call not indented correctly; expected 16 spaces but found 31" source="PEAR.Functions.FunctionCallSignatureSniff"/>
    <error line="236" column="103" severity="error" message="Closing parenthesis of a multi-line function call must be on a line by itself" source="PEAR.Functions.FunctionCallSignatureSniff"/>
    <error line="236" column="105" severity="warning" message="Line exceeds 85 characters; contains 104 characters" source="PEAR.Files.LineLengthSniff"/>
    <error line="237" column="22" severity="error" message="Opening parenthesis of a multi-line function call must be the last content on the line" source="PEAR.Functions.FunctionCallSignatureSniff"/>
    <error line="238" column="1" severity="error" message="Multi-line function call not indented correctly; expected 16 spaces but found 29" source="PEAR.Functions.FunctionCallSignatureSniff"/>
    <error line="238" column="79" severity="error" message="Closing parenthesis of a multi-line function call must be on a line by itself" source="PEAR.Functions.FunctionCallSignatureSniff"/>
    <error line="250" column="13" severity="error" message="Private method name "cbJSGenerator::getFoldersFilesTree" must be prefixed with an underscore" source="PEAR.NamingConventions.ValidFunctionNameSniff"/>
    <error line="263" column="46" severity="error" message="There must be a single space between the closing parenthesis and the openning brace of a multi-line IF statement" source="PEAR.ControlStructures.MultiLineConditionSniff"/>
    <error line="263" column="21" severity="warning" message="Inline control structures are discouraged" source="PEAR.ControlStructures.InlineControlStructureSniff"/>
  </file>
</checkstyle>
<coverage generated="1251979837" phpunit="3.3.17">
  <project name="AllTests" timestamp="1251979837">
    <file name="/opt/cruisecontrol/projects/phpcb/source/src/JSGenerator.php">
      <class name="cbJSGenerator" namespace="global" fullPackage="PHP_CodeBrowser" category="PHP_CodeBrowser" package="PHP_CodeBrowser">
        <metrics methods="5" coveredmethods="2" statements="128" coveredstatements="45" elements="133" coveredelements="47"/>
      </class>
      <line num="0" type="stmt" count="6"/>
      <line num="61" type="stmt" count="1"/>
      <line num="74" type="method" count="8"/>
      <line num="76" type="stmt" count="8"/>
      <line num="77" type="stmt" count="8"/>
      <line num="86" type="method" count="0"/>
      <line num="88" type="stmt" count="0"/>
      <line num="89" type="stmt" count="0"/>
      <line num="90" type="stmt" count="0"/>
      <line num="91" type="stmt" count="0"/>
      <line num="92" type="stmt" count="0"/>
      <line num="93" type="stmt" count="0"/>
      <line num="94" type="stmt" count="0"/>
      <line num="95" type="stmt" count="0"/>
      <line num="96" type="stmt" count="0"/>
      <line num="97" type="stmt" count="0"/>
      <line num="98" type="stmt" count="0"/>
      <line num="99" type="stmt" count="0"/>
      <line num="100" type="stmt" count="0"/>
      <line num="112" type="method" count="1"/>
      <line num="114" type="stmt" count="1"/>
      <line num="115" type="stmt" count="1"/>
      <line num="116" type="stmt" count="1"/>
      <line num="117" type="stmt" count="1"/>
      <line num="118" type="stmt" count="1"/>
      <line num="119" type="stmt" count="1"/>
      <line num="120" type="stmt" count="1"/>
      <line num="122" type="stmt" count="1"/>
      <line num="123" type="stmt" count="1"/>
      <line num="124" type="stmt" count="1"/>
      <line num="125" type="stmt" count="1"/>
      <line num="126" type="stmt" count="1"/>
      <line num="127" type="stmt" count="1"/>
      <line num="128" type="stmt" count="1"/>
      <line num="129" type="stmt" count="1"/>
      <line num="130" type="stmt" count="1"/>
      <line num="133" type="stmt" count="1"/>
      <line num="134" type="stmt" count="1"/>
      <line num="135" type="stmt" count="1"/>
      <line num="136" type="stmt" count="0"/>
      <line num="137" type="stmt" count="0"/>
      <line num="138" type="stmt" count="0"/>
      <line num="140" type="stmt" count="1"/>
      <line num="141" type="stmt" count="0"/>
      <line num="142" type="stmt" count="0"/>
      <line num="144" type="stmt" count="1"/>
      <line num="145" type="stmt" count="0"/>
      <line num="146" type="stmt" count="0"/>
      <line num="149" type="stmt" count="1"/>
      <line num="150" type="stmt" count="0"/>
      <line num="151" type="stmt" count="0"/>
      <line num="152" type="stmt" count="0"/>
      <line num="153" type="stmt" count="0"/>
      <line num="154" type="stmt" count="0"/>
      <line num="155" type="stmt" count="0"/>
      <line num="156" type="stmt" count="0"/>
      <line num="157" type="stmt" count="0"/>
      <line num="158" type="stmt" count="0"/>
      <line num="159" type="stmt" count="0"/>
      <line num="160" type="stmt" count="0"/>
      <line num="161" type="stmt" count="0"/>
      <line num="162" type="stmt" count="0"/>
      <line num="163" type="stmt" count="0"/>
      <line num="164" type="stmt" count="0"/>
      <line num="167" type="stmt" count="1"/>
      <line num="168" type="stmt" count="0"/>
      <line num="169" type="stmt" count="1"/>
      <line num="170" type="stmt" count="0"/>
      <line num="171" type="stmt" count="0"/>
      <line num="173" type="stmt" count="1"/>
      <line num="174" type="stmt" count="1"/>
      <line num="175" type="stmt" count="1"/>
      <line num="176" type="stmt" count="1"/>
      <line num="177" type="stmt" count="1"/>
      <line num="178" type="stmt" count="1"/>
      <line num="179" type="stmt" count="1"/>
      <line num="180" type="stmt" count="1"/>
      <line num="182" type="stmt" count="1"/>
      <line num="184" type="stmt" count="1"/>
      <line num="186" type="stmt" count="0"/>
      <line num="187" type="stmt" count="0"/>
      <line num="188" type="stmt" count="0"/>
      <line num="189" type="stmt" count="0"/>
      <line num="190" type="stmt" count="0"/>
      <line num="191" type="stmt" count="0"/>
      <line num="193" type="stmt" count="0"/>
      <line num="194" type="stmt" count="0"/>
      <line num="196" type="stmt" count="0"/>
      <line num="197" type="stmt" count="0"/>
      <line num="198" type="stmt" count="0"/>
      <line num="199" type="stmt" count="0"/>
      <line num="200" type="stmt" count="0"/>
      <line num="201" type="stmt" count="0"/>
      <line num="202" type="stmt" count="0"/>
      <line num="203" type="stmt" count="0"/>
      <line num="204" type="stmt" count="0"/>
      <line num="205" type="stmt" count="0"/>
      <line num="206" type="stmt" count="1"/>
      <line num="207" type="stmt" count="1"/>
      <line num="208" type="stmt" count="1"/>
      <line num="209" type="stmt" count="1"/>
      <line num="210" type="stmt" count="1"/>
      <line num="211" type="stmt" count="1"/>
      <line num="212" type="stmt" count="1"/>
      <line num="213" type="stmt" count="1"/>
      <line num="214" type="stmt" count="1"/>
      <line num="226" type="method" count="0"/>
      <line num="228" type="stmt" count="0"/>
      <line num="229" type="stmt" count="0"/>
      <line num="230" type="stmt" count="0"/>
      <line num="231" type="stmt" count="0"/>
      <line num="232" type="stmt" count="0"/>
      <line num="233" type="stmt" count="0"/>
      <line num="234" type="stmt" count="0"/>
      <line num="235" type="stmt" count="0"/>
      <line num="236" type="stmt" count="0"/>
      <line num="237" type="stmt" count="0"/>
      <line num="238" type="stmt" count="0"/>
      <line num="240" type="stmt" count="0"/>
      <line num="241" type="stmt" count="0"/>
      <line num="250" type="method" count="0"/>
      <line num="252" type="stmt" count="0"/>
      <line num="253" type="stmt" count="0"/>
      <line num="254" type="stmt" count="0"/>
      <line num="255" type="stmt" count="0"/>
      <line num="256" type="stmt" count="0"/>
      <line num="258" type="stmt" count="0"/>
      <line num="259" type="stmt" count="0"/>
      <line num="260" type="stmt" count="0"/>
      <line num="262" type="stmt" count="0"/>
      <line num="263" type="stmt" count="0"/>
      <line num="264" type="stmt" count="0"/>
      <line num="265" type="stmt" count="0"/>
      <line num="266" type="stmt" count="0"/>
      <line num="267" type="stmt" count="0"/>
      <line num="268" type="stmt" count="0"/>
      <line num="269" type="stmt" count="0"/>
      <line num="271" type="stmt" count="1"/>
      <metrics loc="271" ncloc="166" classes="1" methods="5" coveredmethods="2" statements="133" coveredstatements="48" elements="138" coveredelements="50"/>
    </file>
    <metrics files="16" loc="1835" ncloc="871" classes="12" methods="55" coveredmethods="44" statements="468" coveredstatements="325" elements="523" coveredelements="369"/>
  </project>
</coverage>
<metrics files="16" functions="0" cls="12" clsa="1" clsc="11" roots="5" leafs="6" interfs="0" maxdit="2">
  <file name="/opt/cruisecontrol/projects/phpcb/source/src/JSGenerator.php" classes="1" functions="0" loc="271" cloc="105" ncloc="166" locExecutable="131" locExecuted="46" coverage="35.114504">
    <class name="cbJSGenerator" loc="212" locExecutable="131" locExecuted="46" aif="0.000000" ahf="100.000000" ca="1" ce="1" csz="6" cis="3" coverage="35.114504" dit="0" i="0.500000" impl="0" mif="0.000000" mhf="40.000000" noc="1" pf="0.000000" vars="1" varsnp="0" varsi="1" wmc="34" wmcnp="25" wmci="34">
      <method name="__construct" loc="4" locExecutable="1" locExecuted="1" coverage="100.000000" ccn="1" crap="1.000000" npath="1" parameters="1"/>
      <method name="getJSTree" loc="16" locExecutable="13" locExecuted="0" coverage="0.000000" ccn="1" crap="2.000000" npath="1" parameters="1"/>
      <method name="getHighlightedSource" loc="104" locExecutable="86" locExecuted="43" coverage="50.000000" ccn="23" crap="89.125000" npath="6232513" parameters="3"/>
      <method name="echoJSTreeNodes" loc="16" locExecutable="12" locExecuted="0" coverage="0.000000" ccn="3" crap="12.000000" npath="3" parameters="3"/>
      <method name="getFoldersFilesTree" loc="21" locExecutable="16" locExecuted="0" coverage="0.000000" ccn="6" crap="42.000000" npath="4" parameters="1"/>
    </class>
  </file>
</metrics>
<pmd-cpd version="phpcpd 1.1.1">
  <duplication lines="4" tokens="4">
    <file path="/opt/cruisecontrol/projects/phpcb/source/src/JSGenerator.php" line="250"/>
    <file path="/opt/cruisecontrol/projects/phpcb/source/src/JSGenerator.php" line="272"/>
    <codefragment>    private function testDup ($files)
    {
        $result = array();
        if (is_array($files)) {
</codefragment>
  </duplication>
</pmd-cpd>
<pmd version="PHPUnit 3.3.17">
  <file name="/opt/cruisecontrol/projects/phpcb/source/src/JSGenerator.php">
    <violation rule="CodeCoverage" priority="1" line="86" to-line="101" package="PHP_CodeBrowser" class="cbJSGenerator" method="getJSTree">The code coverage is 0.00 which is considered low.</violation>
    <violation rule="CodeCoverage" priority="1" line="112" to-line="215" package="PHP_CodeBrowser" class="cbJSGenerator" method="getHighlightedSource">The code coverage is 50.00 which is considered medium.</violation>
    <violation rule="CyclomaticComplexity" priority="1" line="112" to-line="215" package="PHP_CodeBrowser" class="cbJSGenerator" method="getHighlightedSource">The cyclomatic complexity is 23. Complexity is determined by the number of decision points in a function or method plus one for the function or method entry. The decision points are "if", "for", "foreach", "while", "case", "catch", "&&", "||", and "?:". Generally, 1-4 is low complexity, 5-7 indicates moderate complexity, 8-10 is high complexity, and 11+ is very high complexity.</violation>
    <violation rule="NPathComplexity" priority="1" line="112" to-line="215" package="PHP_CodeBrowser" class="cbJSGenerator" method="getHighlightedSource">The NPath complexity is 6232513. The NPath complexity of a function or method is the number of acyclic execution paths through that method. A threshold of 200 is generally considered the point where measures should be taken to reduce complexity.</violation>
    <violation rule="CRAP" priority="1" line="112" to-line="215" package="PHP_CodeBrowser" class="cbJSGenerator" method="getHighlightedSource">The CRAP index is 89. The Change Risk Analysis and Predictions (CRAP) index of a function or method uses cyclomatic complexity and code coverage from automated tests to help estimate the effort and risk associated with maintaining legacy code. A CRAP index over 30 is a good indicator of crappy code.</violation>
    <violation rule="CodeCoverage" priority="1" line="226" to-line="241" package="PHP_CodeBrowser" class="cbJSGenerator" method="echoJSTreeNodes">The code coverage is 0.00 which is considered low.</violation>
    <violation rule="CodeCoverage" priority="1" line="250" to-line="270" package="PHP_CodeBrowser" class="cbJSGenerator" method="getFoldersFilesTree">The code coverage is 0.00 which is considered low.</violation>
    <violation rule="CRAP" priority="1" line="250" to-line="270" package="PHP_CodeBrowser" class="cbJSGenerator" method="getFoldersFilesTree">The CRAP index is 42. The Change Risk Analysis and Predictions (CRAP) index of a function or method uses cyclomatic complexity and code coverage from automated tests to help estimate the effort and risk associated with maintaining legacy code. A CRAP index over 30 is a good indicator of crappy code.</violation>
  </file>
</pmd>
<testsuites>
  <testsuite name="AllTests" tests="25" assertions="107" failures="0" errors="0" time="0.397044">
    <testsuite name="cbErrorPMDTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/Plugins/ErrorPMDTest.php" tests="4" assertions="28" failures="0" errors="0" time="0.044240">
      <testsuite name="cbErrorPMDTest::testMapError" tests="1" assertions="17" failures="0" errors="0" time="0.021225">
        <testcase name="testMapError with data set #0" assertions="17" time="0.021225"/>
      </testsuite>
      <testsuite name="cbErrorPMDTest::testMapErrorEmpty" tests="1" assertions="4" failures="0" errors="0" time="0.007997">
        <testcase name="testMapErrorEmpty with data set #0" assertions="4" time="0.007997"/>
      </testsuite>
      <testcase name="testMapErrorFail" class="cbErrorPMDTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/Plugins/ErrorPMDTest.php" line="56" assertions="3" time="0.007568"/>
      <testcase name="testSetPluginName" class="cbErrorPMDTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/Plugins/ErrorPMDTest.php" line="62" assertions="4" time="0.007449"/>
    </testsuite>
    <testsuite name="cbPluginErrorTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/PluginErrorTest.php" tests="3" assertions="10" failures="0" errors="0" time="0.033862">
      <testcase name="test__construct" class="cbPluginErrorTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/PluginErrorTest.php" line="28" assertions="3" time="0.008935"/>
      <testcase name="testParsXMLErrorException" class="cbPluginErrorTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/PluginErrorTest.php" line="36" assertions="3" time="0.010152"/>
      <testcase name="testParseXMLError" class="cbPluginErrorTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/PluginErrorTest.php" line="41" assertions="4" time="0.014775"/>
    </testsuite>
    <testsuite name="cbFDHandlerTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/FDHandlerTest.php" tests="8" assertions="17" failures="0" errors="0" time="0.212749">
      <testcase name="testCopyDirectory" class="cbFDHandlerTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/FDHandlerTest.php" line="26" assertions="4" time="0.156284"/>
      <testcase name="testCopyFile" class="cbFDHandlerTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/FDHandlerTest.php" line="35" assertions="2" time="0.009896"/>
      <testcase name="testCreateDirectory" class="cbFDHandlerTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/FDHandlerTest.php" line="42" assertions="1" time="0.007079"/>
      <testcase name="testCreateFile" class="cbFDHandlerTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/FDHandlerTest.php" line="48" assertions="3" time="0.008663"/>
      <testcase name="testDeleteDirectory" class="cbFDHandlerTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/FDHandlerTest.php" line="62" assertions="3" time="0.007820"/>
      <testcase name="testDeleteFile" class="cbFDHandlerTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/FDHandlerTest.php" line="76" assertions="2" time="0.006803"/>
      <testcase name="testLoadFile" class="cbFDHandlerTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/FDHandlerTest.php" line="84" assertions="1" time="0.008644"/>
      <testcase name="testLoadFileException" class="cbFDHandlerTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/FDHandlerTest.php" line="93" assertions="1" time="0.007560"/>
    </testsuite>
    <testsuite name="cbXMLHandlerTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/XMLHandlerTest.php" tests="4" assertions="14" failures="0" errors="0" time="0.039378">
      <testcase name="test__construct" class="cbXMLHandlerTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/XMLHandlerTest.php" line="41" assertions="4" time="0.011344"/>
      <testcase name="testLoadXML" class="cbXMLHandlerTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/XMLHandlerTest.php" line="61" assertions="2" time="0.007744"/>
      <testcase name="testLoadXMLFromString" class="cbXMLHandlerTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/XMLHandlerTest.php" line="70" assertions="2" time="0.007417"/>
      <testcase name="testSaveXML" class="cbXMLHandlerTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/XMLHandlerTest.php" line="79" assertions="6" time="0.012873"/>
    </testsuite>
    <testsuite name="cbXMLGeneratorTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/XMLGeneratorTest.php" tests="3" assertions="8" failures="0" errors="0" time="0.025562">
      <testsuite name="cbXMLGeneratorTest::testGenerateXMLFromErrors" tests="1" assertions="2" failures="0" errors="0" time="0.010113">
        <testcase name="testGenerateXMLFromErrors with data set #0" assertions="2" time="0.010113"/>
      </testsuite>
      <testcase name="testSetXMLName" class="cbXMLGeneratorTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/XMLGeneratorTest.php" line="46" assertions="2" time="0.007690"/>
      <testsuite name="cbXMLGeneratorTest::testSortErrorList" tests="1" assertions="4" failures="0" errors="0" time="0.007759">
        <testcase name="testSortErrorList with data set #0" assertions="4" time="0.007759"/>
      </testsuite>
    </testsuite>
    <testsuite name="cbErrorHandlerTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/ErrorHandlerTest.php" tests="3" assertions="30" failures="0" errors="0" time="0.041254">
      <testcase name="test__construct" class="cbErrorHandlerTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/ErrorHandlerTest.php" line="27" assertions="3" time="0.008225"/>
      <testcase name="testGetErrorsByFile" class="cbErrorHandlerTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/ErrorHandlerTest.php" line="32" assertions="23" time="0.017691"/>
      <testcase name="testGetFilesWithErrors" class="cbErrorHandlerTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/ErrorHandlerTest.php" line="50" assertions="4" time="0.015338"/>
    </testsuite>
    <testsuite name="cbHTMLGeneratorTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/HTMLGeneratorTest.php" tests="0" assertions="0" failures="0" errors="0" time="0.000000">
      <testsuite name="cbHTMLGeneratorTest::testGenerateViewFlat" tests="0" assertions="0" failures="0" errors="0" time="0.000000"/>
      <testsuite name="cbHTMLGeneratorTest::testGenerateViewReview" tests="0" assertions="0" failures="0" errors="0" time="0.000000"/>
      <testsuite name="cbHTMLGeneratorTest::testGenerateViewTree" tests="0" assertions="0" failures="0" errors="0" time="0.000000"/>
    </testsuite>
    <testsuite name="cbJSGeneratorTest" file="/opt/cruisecontrol/projects/phpcb/source/tests/src/JSGeneratorTest.php" tests="0" assertions="0" failures="0" errors="0" time="0.000000">
      <testsuite name="cbJSGeneratorTest::testGetHighlightedSource" tests="0" assertions="0" failures="0" errors="0" time="0.000000"/>
    </testsuite>
  </testsuite>
</testsuites>
</cruisecontrol>


text:
<configuration>
  <!-- Recommendation: place status listeners towards the the top of the configuration file -->
  <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{30} - %msg%n</pattern>
    </encoder>
  </appender>

  <variable name="default" value="${spez.loglevel.default:-INFO}" />
  <variable name="cdc" value="${spez.loglevel.cdc:-INFO}" />
  <variable name="core" value="${spez.loglevel.core:-INFO}" />
  <variable name="netty" value="${spez.loglevel.netty:-INFO}" />
  <variable name="spannerclient" value="${spez.loglevel.spannerclient:-INFO}" />

  <logger name="com.google.spannerclient.Database" level="${spez.loglevel.spannerclient.Database:-${spannerclient}}"/>
  <logger name="com.google.spannerclient.GrpcClient" level="${spez.loglevel.spannerclient.GrpcClient:-OFF}"/>
  <logger name="com.google.spannerclient.Spanner" level="${spez.loglevel.spannerclient.Spanner:-OFF}"/>
  <logger name="com.google.spannerclient.Util" level="${spez.loglevel.spannerclient.Util:-${spannerclient}}"/>
  <logger name="com.google.spez.cdc.Main" level="${spez.loglevel.cdc.Main:-${cdc}}"/>
  <logger name="com.google.spez.core.EventPublisher" level="${spez.loglevel.cdc.EventPublisher:-${core}}"/>
  <logger name="com.google.spez.core.LptsUpdater" level="${spez.loglevel.cdc.LptsUpdater:-${core}}"/>
  <logger name="com.google.spez.core.RowProcessor" level="${spez.loglevel.cdc.RowProcessor:-${core}}"/>
  <logger name="com.google.spez.core.RowProcessorStats" level="${spez.loglevel.cdc.RowProcessorStats:-${core}}"/>
  <logger name="com.google.spez.core.SpannerTailer" level="${spez.loglevel.cdc.SpannerTailer:-${core}}"/>
  <logger name="com.google.spez.core.Spez" level="${spez.loglevel.cdc.Spez:-${core}}"/>
  <logger name="com.google.spez.core.SpezMetrics" level="${spez.loglevel.cdc.SpezMetrics:-${core}}"/>
  <logger name="com.google.spez.core.SpannerToAvroRecord" level="${spez.loglevel.cdc.SpannerToAvroRecord:-${core}}"/>
  <logger name="com.google.spez.core.SpannerToAvroSchema" level="${spez.loglevel.cdc.SpannerToAvroSchema:-${core}}"/>
  <logger name="io.netty.buffer.AbstractByteBuf" level="${spez.loglevel.netty.AbstractByteBuf:-${netty}}"/>
  <logger name="io.netty.buffer.ByteBufUtil" level="${spez.loglevel.netty.ByteBufUtil:-${netty}}"/>
  <logger name="io.netty.buffer.PoolThreadCache" level="${spez.loglevel.netty.PoolThreadCache:-${netty}}"/>
  <logger name="io.netty.buffer.PooledByteBufAllocator" level="${spez.loglevel.netty.PooledByteBufAllocator:-${netty}}"/>
  <logger name="io.netty.channel.DefaultChannelPipeline" level="${spez.loglevel.netty.DefaultChannelPipeline:-OFF}"/>
  <logger name="io.netty.channel.MultithreadEventLoopGroup" level="${spez.loglevel.netty.MultithreadEventLoopGroup:-${netty}}"/>
  <logger name="io.netty.channel.nio.NioEventLoop" level="${spez.loglevel.netty.NioEventLoop:-${netty}}"/>
  <logger name="io.netty.handler.ssl.CipherSuiteConverter" level="${spez.loglevel.netty.CipherSuiteConverter:-OFF}"/>
  <logger name="io.netty.handler.ssl.OpenSsl" level="${spez.loglevel.netty.OpenSsl:-${netty}}"/>
  <logger name="io.netty.handler.ssl.OpenSslX509TrustManagerWrapper" level="${spez.loglevel.netty.OpenSslX509TrustManagerWrapper:-${netty}}"/>
  <logger name="io.netty.handler.ssl.ReferenceCountedOpenSslClientContext" level="${spez.loglevel.netty.ReferenceCountedOpenSslClientContext:-${netty}}"/>
  <logger name="io.netty.handler.ssl.ReferenceCountedOpenSslContext" level="${spez.loglevel.netty.ReferenceCountedOpenSslContext:-${netty}}"/>
  <logger name="io.netty.util.Recycler" level="${spez.loglevel.netty.Recycler:-${netty}}"/>
  <logger name="io.netty.util.ResourceLeakDetector" level="${spez.loglevel.netty.ResourceLeakDetector:-${netty}}"/>
  <logger name="io.netty.util.ResourceLeakDetectorFactory" level="${spez.loglevel.netty.ResourceLeakDetectorFactory:-${netty}}"/>
  <logger name="io.netty.util.concurrent.AbstractEventExecutor" level="${spez.loglevel.netty.AbstractEventExecutor:-${netty}}"/>
  <logger name="io.netty.util.concurrent.DefaultPromise" level="${spez.loglevel.netty.DefaultPromise:-${netty}}"/>
  <logger name="io.netty.util.concurrent.DefaultPromise.rejectedExecution" level="${spez.loglevel.netty.DefaultPromise.rejectedExecution:-${netty}}"/>
  <logger name="io.netty.util.concurrent.GlobalEventExecutor" level="${spez.loglevel.netty.GlobalEventExecutor:-${netty}}"/>
  <logger name="io.netty.util.concurrent.SingleThreadEventExecutor" level="${spez.loglevel.netty.SingleThreadEventExecutor:-${netty}}"/>
  <logger name="io.netty.util.internal.CleanerJava9" level="${spez.loglevel.netty.CleanerJava9:-${netty}}"/>
  <logger name="io.netty.util.internal.InternalThreadLocalMap" level="${spez.loglevel.netty.InternalThreadLocalMap:-${netty}}"/>
  <logger name="io.netty.util.internal.NativeLibraryLoader" level="${spez.loglevel.netty.NativeLibraryLoader:-OFF}"/>
  <logger name="io.netty.util.internal.PlatformDependent" level="${spez.loglevel.netty.PlatformDependent:-${netty}}"/>
  <logger name="io.netty.util.internal.PlatformDependent0" level="${spez.loglevel.netty.PlatformDependent0:-${netty}}"/>
  <logger name="io.netty.util.internal.SystemPropertyUtil" level="${spez.loglevel.netty.SystemPropertyUtil:-${netty}}"/>
  <logger name="io.netty.util.internal.logging.InternalLoggerFactory" level="${spez.loglevel.netty.InternalLoggerFactory:-${netty}}"/>

  <root level="${spez.loglevel.root:-INFO}">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>


text:
module Marty::Cleaner
  describe CleanAll do
    let(:config_key) { described_class::CONFIG_KEY }

    before(:each) do
      Marty::Config[config_key] = {
        'day' => 'saturday',
        'range' => ['11:00', '13:00']
      }
    end

    after(:each) do
      Timecop.return
    end
  end

  describe CleanAll do
    it 'takes parameters from the config key' do
      allow(Marty::MaintenanceWindow).to receive(:call).and_return(
        {
          'day' => 'saturday',
        'range' => ['11:00', '13:00'],
        'log_days' => 123,
        'mcfly_days' => 231,
        'timestamp_days' => 321
        })
      expect(Logs).to receive(:call).with(123)
      described_class.call
    end

    it 'takes parameters from the config key' do
      allow(Marty::MaintenanceWindow).to receive(:call).and_return(
        {
          'day' => 'saturday',
        'range' => ['11:00', '13:00'],
        'log_days' => 'Doc',
        'mcfly_days' => 'Im from the future'
        })
      expect { described_class.call }.to raise_error(/must be an integer/)
    end
  end

  describe Logs do
    before(:all) do
      Timecop.travel(Time.zone.now + 11.days)
    end

    after(:all) do
      Timecop.return
    end

    it 'removes logs before but not after' do
      Marty::Logger.info('Please keep me')
      Timecop.travel(Time.zone.now - 3.days)
      Marty::Logger.info('Please delete me')
      Timecop.travel(Time.zone.now + 3.days)
      expect { described_class.call(2) }.to change { Marty::Log.count }.by(-1)
    end
  end

  describe McflyModels do
    def create_api_auth
      api_auth = Marty::ApiAuth.new
      api_auth.app_name = Time.zone.today.to_s
      api_auth.api_key = Time.zone.today.to_s
      api_auth.script_name = Time.zone.today.to_s
      api_auth.user_id = Mcfly.whodunnit.id
      api_auth.o_user_id = Mcfly.whodunnit.id
      api_auth.created_dt = Time.zone.now
      api_auth.obsoleted_dt = Time.zone.now
      api_auth.group_id = 999
      api_auth.save(validate: false)
    end

    it 'removes models of various kinds based on obsoleted date' do
      described_class::CLASSES_TO_CLEAN = [
        ::Marty::ApiAuth
      ]
      Mcfly.whodunnit = Marty::User.find_by(login: 'marty')

      Timecop.travel(Time.zone.now - 5.days)
      create_api_auth

      Timecop.return
      create_api_auth

      expect { described_class.call(2) }.
      to change { Marty::ApiAuth.count }.by(-1)
    end
  end

  describe TimestampModels do
    def create_user
      Marty::User.create!(
        created_at: Time.zone.now,
        updated_at: Time.zone.now,
        login: Time.zone.today.to_s,
        firstname: Time.zone.today.to_s,
        lastname: Time.zone.today.to_s,
        active: false
      )
    end
    it 'removes models based on their last updated_dt' do
      described_class::CLASSES_TO_CLEAN = [
        ::Marty::User
      ]

      Timecop.travel(Time.zone.now - 10.days)
      create_user

      Timecop.return
      create_user

      expect { described_class.call(2) }.
      to change { Marty::User.count }.by(-1)
    end
  end
end


text:
from PyQt5 import QtGui

from PyQt5.QtCore import QEvent, Qt, QPoint, QRectF, QPointF
from PyQt5.QtGui import QLinearGradient, QColor, QPen
from PyQt5.QtWidgets import QWidget

from Data.Vertex import Vertex
from GUI.init import is_dark_theme
from GUI.Widgets.NewDrawers import create_pens

class CalcSheetView(QWidget):
	def __init__(self, parent, document, main_window):
		QWidget.__init__(self, parent)
		self._main_window = main_window
		self._doc = document
		self._sheet = None
		self.setMouseTracking(True)
		self._scale = 1.0
		self._is_dark_theme = is_dark_theme()
		self._mouse_position = None
		self._offset = Vertex()
		self.installEventFilter(self)

	def set_calc_sheet(self, sheet):
		self._sheet = sheet
		self.update()

	def eventFilter(self, obj, event):
		if event.type() == QEvent.KeyPress:
			if event.key() == Qt.Key_Delete:
				self.on_delete()
				return True
			if event.key() == Qt.Key_Control:
				self._states.multi_select = True
			if event.key() == Qt.Key_Escape:
				self.on_escape()
		if event.type() == QEvent.KeyRelease:
			if event.key() == Qt.Key_Control:
				self._states.multi_select = False
		if event.type() == QEvent.GraphicsSceneMouseDoubleClick:
			print("double click")
		return False

	def mouseReleaseEvent(self, q_mouse_event):
		pass

	def mousePressEvent(self, q_mouse_event):
		pass

	def mouseMoveEvent(self, q_mouse_event):
		position = q_mouse_event.pos()
		if self._mouse_position is not None:
			mouse_move_x = self._mouse_position.x() - position.x()
			mouse_move_y = self._mouse_position.y() - position.y()
		else:
			mouse_move_x = 0
			mouse_move_y = 0
		self._mouse_position = position

	# if self._states.middle_button_hold:
	#  self._offset.x -= mouse_move_x / self._scale
	#  self._offset.y += mouse_move_y / self._scale

	# if self._states.middle_button_hold:
	#  self.update()

	def wheelEvent(self, event):
		if self._mouse_position is not None:
			delta = event.angleDelta().y() / 8
			if self._scale + self._scale * (delta * 0.01) > 0:
				self._scale += self._scale * (delta * 0.01)
				width = self.width() / 2
				height = self.height() / 2
				scale = self._scale
				x = self._mouse_position.x() - width
				y = self._mouse_position.y() - height
				distx = x / scale
				disty = y / scale
				self._offset.x -= distx * (delta * 0.01)
				self._offset.y += disty * (delta * 0.01)
				self.update()

	def paintEvent(self, event):
		qp = QtGui.QPainter()
		qp.begin(self)
		p1 = QPoint(0, 0)
		p2 = QPoint(self.width(), self.height())
		p3 = QPoint(0, self.height())
		gradient = QLinearGradient(p1, p3)
		if self._is_dark_theme:
			gradient.setColorAt(0, QColor(80, 80, 90))
			gradient.setColorAt(1, QColor(50, 50, 60))
		else:
			gradient.setColorAt(0, QColor(220, 220, 230))
			gradient.setColorAt(1, QColor(170, 170, 180))
		qp.fillRect(event.rect(), gradient)
		qp.setRenderHint(QtGui.QPainter.Antialiasing)
		self.draw_sheet(event, qp)
		qp.end()

	def draw_sheet(self, event, qp):
		if self._sheet is not None:
			sc = self._scale
			border_pen = QPen(QtGui.QColor(0, 0, 0), 0.0005 * sc)
			pens = create_pens(self._doc, sc)
			half_width = self.width() / 2
			half_height = self.height() / 2
			center = Vertex(half_width, half_height)
			cx = self._offset.x * sc + half_width
			cy = -self._offset.y * sc + half_height
			rect = QRectF(QPointF(cx, cy), QPointF(cx + self._sheet.size[0] * sc, cy - self._sheet.size[1] * sc))
			qp.fillRect(rect, QColor(255, 255, 255))
			self.draw_border(event, qp, cx, cy, border_pen)

	def draw_border(self, event, qp, cx, cy, border_pen):
		sc = self._scale
		sz = self._sheet.size
		shadow_pen = QPen(QtGui.QColor(150, 150, 150), 2)
		rect = QRectF(QPointF(cx, cy), QPointF(cx + sz[0] * sc, cy - sz[1] * sc))
		qp.setPen(shadow_pen)
		qp.drawRect(rect)