private static void recordMoves(final int player, final int pieceMovingType,
									final long pieceMask, final long moves,
									final long enemyAttacks, final long enemyPieces,
									final long promotionMask,
									final MoveList mlist, final State4 s, final FeatureSet f) {

		if (pieceMask != 0 && moves != 0) {

			final int[] mailbox = s.mailbox;
			final long piece = pieceMask & -pieceMask;

			for (long m = moves; m != 0; m &= m - 1) {
				final long move = m & -m;
				final int moveIndex = BitUtil.lsbIndex(move);

				//bonus for direct material gain from the move
				int gain;
				if((move & enemyPieces) != 0){
					final int takenValue = pieceValue[mailbox[moveIndex]];
					final int movingPieceValue = pieceValue[pieceMovingType];

					gain = takenValue - movingPieceValue/10;

					if(takenValue < movingPieceValue && (enemyAttacks & move) != 0){
						//apply penalty because in the short term there is possibility
						//of retaking the piece on opp. next turn for opp. material gain
						gain -= 50;
					}
				} else{
					gain = 0;
				}

				int historyWeight = f != null? getMoveWeight(player, pieceMovingType, piece, move, f, s) * 50 / maxWeight: 0;

				int baseRank = gain + historyWeight;

				if(pieceMovingType == State4.PIECE_TYPE_PAWN && (move & promotionMask) != 0){
					mlist.add(piece, move, baseRank + PieceWeights.queen, State4.PROMOTE_QUEEN);
					mlist.add(piece, move, baseRank + PieceWeights.knight, State4.PROMOTE_KNIGHT);
				} else{
					//non-pawn movement
					mlist.add(piece, move, baseRank);
				}
			}
		}
	}