text:
package jbridge.comm.binstream;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;

import inou.net.rpc.BinServer;
import inou.net.rpc.ICommunicator;
import inou.net.rpc.IMessageHandler;
import inou.util.CommandLine;
import jbridge.BridgeServer;
import jbridge.IBridgeBuilder;
import jbridge.IObjectTransformer;
import jbridge.IOverrideCall;
import jbridge.ISessionProcedure;
import org.apache.log4j.Logger;

public class BStream_JBServer implements IBridgeBuilder {

	private Logger monitor = Logger.getLogger(this.getClass());
	private BridgeServer bridgeServer;
	private ICommunicator bserver;
	private IOverrideCall overrideCaller;
	private HashMap handlerMap;

	public BStream_JBServer() {
	}

	public void setConfig(CommandLine cli) throws IOException {
		int port = cli.getOptionInteger("remoteport",-1);
		if (port == -1) {
			throw new RuntimeException("Port number is not specified.");
		}
		bserver = new BinServer(port);
		overrideCaller = new BStream_OverrideCall(bserver);
		registHandlers();
	}

	public IObjectTransformer getObjectTransformer() {
		return transformer;
	}

	public IOverrideCall getOverrideCaller() {
		return overrideCaller;
	}

	public void start(BridgeServer bs) {
		this.bridgeServer = bs;
		bserver.start();
	}

	private static void printHelp() {
		System.out.println("=== BinStream BridgeBuilder ");
		System.out.println("     -remotehost:localhost (client hostname)\n");
		System.out.println("     -remoteport:9009 (client service port)\n");
	}

	private IObjectTransformer transformer = new IObjectTransformer() {
			public Object exportFilter(Object arg) {
				if (arg == null) return null;
				if (arg.getClass().isPrimitive() || arg instanceof String ||
					arg instanceof Integer || arg instanceof Double ||
					arg instanceof Byte || arg instanceof Float ||
					arg instanceof Long || arg instanceof Short ||
					arg instanceof Boolean) {
					return arg;
				}
				return null;
			}

			public Object importFilter(Object obj) {
				return obj;
			}
		};

	private void registHandlers() {
		handlerMap = new HashMap();
		handlerMap.put("call",h_call);
		handlerMap.put("new",h_new);
		handlerMap.put("superCall",h_superCall);
		handlerMap.put("classname",h_classname);
		handlerMap.put("static",h_static);
		handlerMap.put("ref",h_ref);
		handlerMap.put("set",h_set);
		handlerMap.put("sessionCall",h_sessionCall);
		handlerMap.put("extend",h_extend);
		handlerMap.put("classinfo",h_classinfo);
		handlerMap.put("impl",h_impl);
		handlerMap.put("import",h_import);
		handlerMap.put("unlink",h_unlink);
		handlerMap.put("addClassLoader",h_addClassLoader);
		handlerMap.put("removeClassLoader",h_removeClassLoader);
		handlerMap.put("exit",h_exit);
		handlerMap.put("allObjects",h_allObjects);
		handlerMap.put("dump",h_dump);

		for(Iterator it = handlerMap.keySet().iterator();it.hasNext();) {
			String k = (String)it.next();
			IMessageHandler h = (IMessageHandler)handlerMap.get(k);
			bserver.addHandler(k,h);
		}
	}

	private Object dispach(String method,Object[] args) throws Exception {
		IMessageHandler h = (IMessageHandler)handlerMap.get(method);
		if (h != null) {
			return h.send(args);
		} else {
			throw new IOException("No such remote method: "+method);
		}
	}

	private void checkArgNumbers(int num,Object[] args) throws IOException {
		if (num == 0 && args == null) return;
		if (args.length == num) return;
		throw new IOException("Wrong argument number: expected="+num+"  but received="+args.length);
	}

	private void checkArgNumbersPlus(int num,Object[] args) throws IOException {
		if (num == 0 && args == null) return;
		if (args.length >= num) return;
		throw new IOException("Wrong argument number: expected="+num+"  but received="+args.length);
	}

	private static Object[] cdr(Object[] v) {
		return cdr(v,1);
	}

	private static Object[] cdr(Object[] v,int skip) {
		Object[] ret = new Object[v.length-skip];
		for (int i=0;i<ret.length;i++) {
			ret[i] = v[i+skip];
		}
		return ret;
	}

	private IMessageHandler h_call = new IMessageHandler() {
			public Object send(Object[] args) throws Exception {
				checkArgNumbersPlus(2,args);
				Object proxyId = args[0];
				String methodName = (String)args[1];
				return bridgeServer.call(proxyId,methodName,cdr(args,2));
			}
		};

	private IMessageHandler h_new = new IMessageHandler() {
			public Object send(Object[] args) throws Exception {
				checkArgNumbersPlus(1,args);
				String fqcn = (String)args[0];
				return bridgeServer.jnew(fqcn,cdr(args));
			}
		};

	private IMessageHandler h_superCall = new IMessageHandler() {
			public Object send(Object[] args) throws Exception {
				checkArgNumbersPlus(2,args);
				Object proxyId = args[0];
				String methodName = (String)args[1];
				return bridgeServer.superCall(proxyId,methodName,cdr(args,2));
			}
		};

	private IMessageHandler h_classname = new IMessageHandler() {
			public Object send(Object[] args) throws Exception {
				checkArgNumbers(1,args);
				return bridgeServer.inspectClassname(args[0]);
			}
		};

	private IMessageHandler h_static = new IMessageHandler() {
			public Object send(Object[] args) throws Exception {
				checkArgNumbers(1,args);
				String fqcn = (String)args[0];
				return bridgeServer.getStaticClass(fqcn);
			}
		};

	private IMessageHandler h_ref = new IMessageHandler() {
			public Object send(Object[] args) throws Exception {
				checkArgNumbers(2,args);
				Object proxyId = args[0];
				String fieldName = (String)args[1];
				return bridgeServer.ref(proxyId,fieldName);
			}
		};

	private IMessageHandler h_set = new IMessageHandler() {
			public Object send(Object[] args) throws Exception {
				checkArgNumbers(3,args);
				Object proxyId = args[0];
				String fieldName = (String)args[1];
				Object val = args[2];
				bridgeServer.set(proxyId,fieldName,val);
				return null;
			}
		};

	private IMessageHandler h_sessionCall = new IMessageHandler() {
			public Object send(Object[] args) throws Exception {
				checkArgNumbersPlus(2,args);
				Object sid = args[0];
				final String nestedMethod = (String)args[1];
				final Object[] targs = cdr(args,2);
				ISessionProcedure sp = new ISessionProcedure() {
						public String getTitle() { return nestedMethod; }
						public Object exec() throws Exception {
							return dispach(nestedMethod,targs);
						}
					};
				return bridgeServer.sessionCall(sid,sp);
			}
		};

	private IMessageHandler h_extend = new IMessageHandler() {
			public Object send(Object[] args) throws Exception {
				checkArgNumbersPlus(1,args);
				String fqcn = (String)args[0];
				return bridgeServer.jextend(fqcn,cdr(args));
			}
		};

	private IMessageHandler h_classinfo = new IMessageHandler() {
			public Object send(Object[] args) throws Exception {
				checkArgNumbers(1,args);
				String fqcn = (String)args[0];
				return bridgeServer.getClassInfo(fqcn);
			}
		};

	private IMessageHandler h_impl = new IMessageHandler() {
			public Object send(Object[] args) throws Exception {
				checkArgNumbers(3,args);
				Object proxyId = args[0];
				String name = (String)args[1];
				Boolean flag = (Boolean)args[2];
				bridgeServer.setImplementFlag(proxyId,name,flag);
				return null;
			}
		};

	private IMessageHandler h_import = new IMessageHandler() {
			public Object send(Object[] args) throws Exception {
				checkArgNumbers(1,args);
				String lines = (String)args[0];
				bridgeServer.jimport(lines);
				return null;
			}
		};

	private IMessageHandler h_unlink = new IMessageHandler() {
			public Object send(Object[] args) throws Exception {
				checkArgNumbers(1,args);
				Object proxyId = args[0];
				bridgeServer.unlink(proxyId);
				return null;
			}
		};

	private IMessageHandler h_addClassLoader = new IMessageHandler() {
			public Object send(Object[] args) throws Exception {
				checkArgNumbers(1,args);
				Object proxyId = args[0];
				bridgeServer.addClassLoader(proxyId);
				return null;
			}
		};

	private IMessageHandler h_removeClassLoader = new IMessageHandler() {
			public Object send(Object[] args) throws Exception {
				checkArgNumbers(1,args);
				Object proxyId = args[0];
				bridgeServer.removeClassLoader(proxyId);
				return null;
			}
		};

	private IMessageHandler h_exit = new IMessageHandler() {
			public Object send(Object[] args) throws Exception {
				//checkArgNumbers(0,args);
				bridgeServer.exit();
				return "EXIT";
			}
		};

	private IMessageHandler h_allObjects = new IMessageHandler() {
			public Object send(Object[] args) throws Exception {
				return bridgeServer.getAllObjectKeys();
			}
		};

	private IMessageHandler h_dump = new IMessageHandler() {
			public Object send(Object[] args) throws Exception {
				checkArgNumbers(0,args);
				bridgeServer.dumpObjects();
				return "DUMP";
			}
		};

}


text:
package analysis

import (
	"bytes"
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"github.com/xlplbo/trans/dic"
	ft "github.com/xlplbo/trans/filetool"
	"github.com/xlplbo/trans/log"
)

type grl struct {
	limit chan struct{}
	wg    *sync.WaitGroup
}

func newgrl(n int) *grl {
	if n <= 0 {
		panic(fmt.Sprintf("goroutine num(%d) must be greater than zero", n))
	}
	return &grl{
		limit: make(chan struct{}, n),
		wg:    &sync.WaitGroup{},
	}
}

func (g *grl) AddOne() {
	g.limit <- struct{}{}
	g.wg.Add(1)
}

func (g *grl) Done() {
	<-g.limit
	g.wg.Done()
}

func (g *grl) Wait() {
	g.wg.Wait()
}

type delegate interface {
	GetString(text []byte) ([][]byte, []int, []int, error)
	Pretreat(trans []byte) []byte
}

// 忽略文件拷贝情况
const (
	IgnoreNotCopy = iota
	IgnoreFirstCopy
	IgnoreAlwaysCopy
)

var (
	rulesMap     = make(map[string]string)
	implMap      = make(map[string]delegate)
	writeHook    = make(map[string][]string)
	wg           = newgrl(512)
	ingoreDefine = make(map[string]*regexp.Regexp)
	ingoreAttrs  = make(map[string]int)
)

//Rules define
const (
	RuleLua       = "lua_rules"
	RulePrefab    = "prefab_rules"
	RuleTablefile = "table_rules"
	RuleCommon    = "common_rules"
	RuleGeneric   = "generic_rules"
	RulePhp       = "php_rules"
	RuleJsonfile  = "json_rules"
	RuleExml      = "exml_rules"
)

func duration(invocation time.Time, name string) {
	elapsed := time.Since(invocation)
	log.WriteLog(log.FILE|log.PRINT, log.INFO, "%s lasted %s", name, elapsed)
}

func getPool(file string) (delegate, error) {
	fileEx := filepath.Ext(file)
	if rule, ok := rulesMap[fileEx]; ok {
		if impl, ok := implMap[rule]; ok {
			return impl, nil
		}
	}
	return nil, fmt.Errorf("[not support file] %s", file)
}

// InitFilter init
func InitFilter(filters [][]byte) {
	sep := fmt.Sprintf("\\%s", string(filepath.Separator))
	asterisk := fmt.Sprintf("[^\\.%s]+", sep)
	for _, line := range filters {
		if line[0] == 0x3b {
			continue
		}
		v := bytes.Split(line, []byte("|"))
		if len(v) != 2 {
			panic(fmt.Sprintf("ignore conf rule error: %s", line))
		}
		key := string(v[0])
		attr := string(v[1])
		if _, ok := ingoreDefine[key]; ok {
			panic(fmt.Sprintf("ignore conf key repeat: %s", key))
		}
		sformat := strings.Replace(key, "\\", sep, -1)
		sformat = strings.Replace(sformat, "/", sep, -1)
		repl := []string{"+", ".", "^", "$", "(", ")", "[", "]", "{", "}"}
		for _, e := range repl {
			sformat = strings.Replace(sformat, e, fmt.Sprintf("\\%s", e), -1)
		}
		sformat = strings.Replace(sformat, "*", asterisk, -1)
		sformat = fmt.Sprintf("%s%s", sep, sformat)
		ingoreDefine[key] = regexp.MustCompile(sformat)
		switch attr {
		case "notcopy":
			ingoreAttrs[key] = IgnoreNotCopy
		case "firstcopy":
			ingoreAttrs[key] = IgnoreFirstCopy
		case "alwayscopy":
			ingoreAttrs[key] = IgnoreAlwaysCopy
		default:
			panic(fmt.Sprintf("ignore conf attr undefine: %s", attr))
		}
		log.WriteLog(log.FILE, log.INFO, "[filter regexp] key=%s, attr=%s, reg=%s", key, attr, sformat)
	}
}

func filter(name string) (bool, int) {
	for k, r := range ingoreDefine {
		if ok := r.MatchString(name); ok {
			log.WriteLog(log.FILE, log.INFO, "[ignore file] %s", name)
			return true, ingoreAttrs[k]
		}
	}
	return false, -1
}

//Register Const Rules
func Register(ext string, impl delegate) {
	if _, ok := implMap[ext]; ok {
		log.WriteLog(log.FILE|log.PRINT, log.ERROR, "[rigster repeat] %s", ext)
		return
	}
	implMap[ext] = impl
}

//SetRulesMap set file ext to rule string
func SetRulesMap(k, v string) {
	ext := filepath.Ext(k)
	if _, ok := rulesMap[ext]; ok {
		log.WriteLog(log.FILE|log.PRINT, log.ERROR, "[rule repeat] %s:%s", ext, v)
		return
	}
	if _, ok := implMap[v]; !ok {
		log.WriteLog(log.FILE|log.PRINT, log.ERROR, "[rule not exsit] %s:%s", ext, v)
		return
	}
	rulesMap[ext] = v
}

//InsertWriteHook init
func InsertWriteHook(key, text, repl string) {
	writeHook[key] = append(writeHook[key], text)
	writeHook[key] = append(writeHook[key], repl)
}

//WriteHook replace
func WriteHook(name string, context []byte) []byte {
	ext := filepath.Ext(name)
	if repl, ok := writeHook[ext]; ok {
		for i := 0; i < len(repl); i += 2 {
			context = bytes.Replace(context, []byte(repl[i]), []byte(repl[i+1]), -1)
		}
	}
	return context
}

//GetString get string from files
func GetString(dbname, update, root string, clean bool) {
	defer duration(time.Now(), "getstring")
	totalfile := 0
	ignore := uint64(0)
	dbdata, err := dic.LoadTabFile(dbname)
	if err != nil {
		log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
		if dbdata == nil {
			return
		}
	}
	notrans := dic.New()
	pathv := filepath.SplitList(root)
	for _, path := range pathv {
		path = filepath.Clean(path)
		log.WriteLog(log.FILE|log.PRINT, log.INFO, "extract literals from %s", path)
		fmap, err := ft.GetAllFiles(path)
		if err != nil {
			log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
			continue
		}
		totalfile += len(fmap)
		for i := 0; i < len(fmap); i++ {
			wg.AddOne()
			go func(file string) {
				defer wg.Done()
				if ok, _ := filter(file); ok {
					atomic.AddUint64(&ignore, 1)
					return
				}
				context, err := ft.ReadAll(file)
				if err != nil {
					log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
					return
				}
				ins, err := getPool(file)
				if err != nil {
					log.WriteLog(log.FILE, log.INFO, err.Error())
					return
				}
				entry, _, _, err := ins.GetString(context)
				if err != nil {
					panic(fmt.Sprintf("%s: %s", file, err))
				}
				for _, v := range entry {
					if _, ok := dbdata.Query(v); !ok {
						notrans.Append(v, []byte(""))
						log.WriteDebug("%s\t%s", v, file)
					}
				}
			}(fmap[i])
		}
		wg.Wait()
	}
	if clean {
		discard, err := dbdata.SaveTabFile(dbname)
		if err != nil {
			log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
			return
		}
		log.WriteLog(log.FILE|log.PRINT, log.INFO, "clean out outdated entries: %d", discard)
	}
	if newcount, err := notrans.SaveXlsx(update); err != nil {
		log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
	} else {
		ignoreCount := atomic.LoadUint64(&ignore)
		if newcount > 0 {
			log.WriteLog(log.FILE|log.PRINT, log.INFO, "generate %s, new line number: %d, ignored files %d, total files %d. finished!", update, newcount, ignoreCount, totalfile)
		} else {
			log.WriteLog(log.FILE|log.PRINT, log.INFO, "nothing to do, ignored files %d, total files %d. finished!", ignoreCount, totalfile)
		}
	}
}

//Translate translate file or path
func Translate(dbname, update, root, output string, clean bool) {
	defer duration(time.Now(), "translate")
	pathv1 := filepath.SplitList(root)
	pathv2 := filepath.SplitList(output)
	if len(pathv1) != len(pathv2) {
		log.WriteLog(log.FILE|log.PRINT, log.ERROR, "params error %s:%s", root, output)
		return
	}
	dbdata, err := dic.LoadTabFile(dbname)
	if err != nil {
		log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
		if dbdata == nil {
			return
		}
	}
	notrans := dic.New()
	totalfile := 0
	ignore := uint64(0)
	fwork := func(oldfile, newfile string) {
		defer wg.Done()
		var (
			bv      []byte
			newbv   []byte
			ins     delegate
			err     error
			entry   [][]byte
			start   []int
			end     []int
			context [][]byte
			nStart  int
			nSize   int
		)
		if ok, kind := filter(oldfile); ok {
			atomic.AddUint64(&ignore, 1)
			switch kind {
			case IgnoreNotCopy:
			case IgnoreFirstCopy:
				_, errExsit := os.Stat(newfile)
				if errExsit != nil {
					bv, err = ft.ReadAll(oldfile)
					if err != nil {
						log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
					} else {
						if err = ft.WriteAll(newfile, bv); err != nil {
							log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
						}
					}
				}
			case IgnoreAlwaysCopy:
				bv, err = ft.ReadAll(oldfile)
				if err != nil {
					log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
				} else {
					if err = ft.WriteAll(newfile, bv); err != nil {
						log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
					}
				}
			}
			return
		}
		bv, err = ft.ReadAll(oldfile)
		if err != nil {
			log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
			return
		}
		ins, err = getPool(oldfile)
		if err != nil {
			log.WriteLog(log.FILE, log.INFO, err.Error())
			goto Point
		}
		entry, start, end, err = ins.GetString(bv)
		if err != nil {
			panic(fmt.Sprintf("%s: %s", oldfile, err))
		}
		nStart = 0
		nSize = len(bv)
		for i := 0; i < len(entry); i++ {
			context = append(context, bv[nStart:start[i]])
			nStart = end[i]
			if trans, ok := dbdata.Query(entry[i]); ok {
				if len(trans) > 0 {
					context = append(context, ins.Pretreat(trans))
				} else {
					context = append(context, bv[start[i]:end[i]])
					notrans.Append(entry[i], []byte(""))
					log.WriteDebug("%s\t%s", entry[i], oldfile)
				}
			} else {
				context = append(context, bv[start[i]:end[i]])
				notrans.Append(entry[i], []byte(""))
				log.WriteDebug("%s\t%s", entry[i], oldfile)
			}
		}
		if nStart < nSize {
			context = append(context, bv[nStart:nSize])
		}
	Point:
		newbv, err = ft.ReadAll(newfile)
		if len(context) > 0 {
			tempbv := bytes.Join(context, []byte(""))
			tempbv = WriteHook(newfile, tempbv)
			if err != nil || bytes.Compare(newbv, tempbv) != 0 {
				if err = ft.WriteAll(newfile, tempbv); err != nil {
					log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
				}
			}
		} else {
			bv = WriteHook(newfile, bv)
			if err != nil || bytes.Compare(newbv, bv) != 0 {
				if err = ft.WriteAll(newfile, bv); err != nil {
					log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
				}
			}
		}
	}
	for i := 0; i < len(pathv1); i++ {
		path1 := filepath.Clean(pathv1[i])
		path2 := filepath.Clean(pathv2[i])
		log.WriteLog(log.FILE|log.PRINT, log.INFO, "translate %s to %s", path1, path2)
		fmap, err := ft.GetAllFiles(path1)
		if err != nil {
			log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
			return
		}
		totalfile += len(fmap)
		for i := 0; i < len(fmap); i++ {
			fpath := strings.Replace(fmap[i], path1, path2, 1)
			wg.AddOne()
			go fwork(fmap[i], fpath)
		}
		wg.Wait()
	}
	if clean {
		discard, err := dbdata.SaveTabFile(dbname)
		if err != nil {
			log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
			return
		}
		log.WriteLog(log.FILE|log.PRINT, log.INFO, "clean out outdated entries: %d", discard)
	}
	if newcount, err := notrans.SaveXlsx(update); err != nil {
		log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
	} else {
		ignoreCount := atomic.LoadUint64(&ignore)
		if newcount > 0 {
			log.WriteLog(log.FILE|log.PRINT, log.INFO, "generate %s, new line number: %d, ignored files %d, total files %d. finished!", update, newcount, ignoreCount, totalfile)
		} else {
			log.WriteLog(log.FILE|log.PRINT, log.INFO, "all files are translated, ignored files %d, total files %d. finished!", ignoreCount, totalfile)
		}
	}
}

//Update update dict
func Update(dbname, update string) {
	defer duration(time.Now(), "update")
	log.WriteLog(log.FILE|log.PRINT, log.INFO, "update %s to %s", update, dbname)
	dbdata, err := dic.LoadTabFile(dbname)
	if err != nil {
		log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
		if dbdata == nil {
			return
		}
	}
	newdata, err := dic.LoadXlsx(update)
	if err != nil {
		log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
		if newdata == nil {
			return
		}
	}
	key, trans := newdata.GetData()
	length := len(key)
	if length > 0 {
		for i := 0; i < length; i++ {
			dbdata.Append(key[i], trans[i])
		}
		if count, err := dbdata.SaveTabFile(dbname); err != nil {
			log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
		} else {
			log.WriteLog(log.FILE|log.PRINT, log.INFO, "update new line: %d, total %d. finished!", length, count)
		}
	} else {
		log.WriteLog(log.FILE|log.PRINT, log.INFO, "nothing to do. finished!")
	}
}

//Transcoding file
func Transcoding(input, sdecode, output, sencode string) {
	input = filepath.Clean(input)
	output = filepath.Clean(output)
	log.WriteLog(log.FILE|log.PRINT, log.INFO, "transcoding %s to %s", input, output)
	filemap, err := ft.GetAllFiles(input)
	if err != nil {
		log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
		return
	}
	decoder, err := ft.GetDecoder(sdecode)
	if err != nil {
		log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
		return
	}
	encoder, err := ft.GetEncoder(sencode)
	if err != nil {
		log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
		return
	}
	count := 0
	for i := 0; i < len(filemap); i++ {
		context, err := ft.ReadAllByEncoding(filemap[i], decoder)
		if err != nil {
			log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
			continue
		}
		path := strings.Replace(filemap[i], input, output, 1)
		if err := ft.WriteAllByEncoding(path, context, encoder); err != nil {
			log.WriteLog(log.FILE|log.PRINT, log.ERROR, err.Error())
			continue
		}
		count++
	}
	log.WriteLog(log.FILE|log.PRINT, log.INFO, "Converts %s to %s, %d/%d files, finished.", sdecode, sencode, count, len(filemap))
}

redpajama_set_name: RedPajamaGithub


text:
require 'thread'

class PDF::Reader

  # Throughout the pdf-reader codebase, repeated calculations which can benefit
  # from caching are made In some cases, caching and reusing results can not
  # only save CPU cycles but also greatly reduce memory requirements But at the
  # same time, we don't want to throw away thread safety We have two
  # interchangeable thread-safe cache implementations:
  class SynchronizedCache
    def initialize
      @cache = {}
      @mutex = Mutex.new
    end
    def [](key)
      @mutex.synchronize { @cache[key] }
    end
    def []=(key,value)
      @mutex.synchronize { @cache[key] = value }
    end
  end
end


text:
<!DOCTYPE html>

    <meta charset="UTF-8">
    <meta name="module-info" content="status=complete" />
    <title>底部条</title>

    <link rel="stylesheet" type="text/css" href="../../../src/ui/core/base.css"/>
    <link rel="stylesheet" type="text/css" href="../../../src/ui/core/common.css"/>
    <link rel="stylesheet" type="text/css" href="../../../src/ui/layout/grid.css"/>

    <link rel="stylesheet" type="text/css" href="../../../src/ui/page/topbar.css" />

                    Host By XXXX
                    Copyright © 2011-2012 jPlusUI Team


text:
namespace MyShare.Kernel.Domain
{
    internal class AggregateDescriptor
    {
        public AggregateRoot Aggregate { get; set; }
        public int Version { get; set; }
    }
}


text:
package ru.ptf.sandbox;

import org.testng.Assert;
import org.testng.annotations.Test;
import ru.pft.sandbox.Equation;

/**
 * Created by Солнышко on 12.03.2017.
 */
public class EquationTests {

  @Test
  public void test0(){
    Equation e = new Equation(1,1,1);
    Assert.assertEquals(e.rootNumber(),0);
  }

  @Test
  public void test1(){
    Equation e = new Equation(1,2,1);
    Assert.assertEquals(e.rootNumber(),1);
  }

  @Test
  public void test2(){
    Equation e = new Equation(1,5,6);
    Assert.assertEquals(e.rootNumber(),2);
  }

  @Test
  public void testLinear(){
    Equation e = new Equation(0,1,1);
    Assert.assertEquals(e.rootNumber(),1);
  }

  @Test
  public void testConstant(){
    Equation e = new Equation(0,0,1);
    Assert.assertEquals(e.rootNumber(),0);
  }

  @Test
  public void testZero(){
    Equation e = new Equation(0,0,0);
    Assert.assertEquals(e.rootNumber(),-1);
  }
}


text:
/* TEMPLATE GENERATED TESTCASE FILE
Filename: CWE672_Operation_on_Resource_After_Expiration_or_Release__list_int_06.cpp
Label Definition File: CWE672_Operation_on_Resource_After_Expiration_or_Release__list_int.label.xml
Template File: sources-sinks-06.tmpl.cpp
*/
/*
 * @description
 * CWE: 672 Operation on Resource After Expiration or Release
 * BadSource:  Add values to the list, including the number zero
 * GoodSource: Add value to the list that are not zero
 * Sinks:
 *    GoodSink: Iterate through the list without attempting to clear its contents
 *    BadSink : Iterate through the list, but clear the list if it contains a zero
 * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5)
 *
 * */

#include "std_testcase.h"

#include <wchar.h>
#include <list>
#include <iostream>

using namespace std;

/* The variable below is declared "const", so a tool should be able
   to identify that reads of this will always give its initialized
   value. */
static const int STATIC_CONST_FIVE = 5;

namespace CWE672_Operation_on_Resource_After_Expiration_or_Release__list_int_06
{

#ifndef OMITBAD

void bad()
{
    list<int>  data;
    if(STATIC_CONST_FIVE==5)
    {
        /* POTENTIAL FLAW: Insert a zero into the list */
        data.push_back(100);
        data.push_back(0);
    }
    if(STATIC_CONST_FIVE==5)
    {
        {
            list<int> ::iterator i;
            cout << "The list contains: ";
            for( i = data.begin(); i != data.end(); i++)
            {
                if (!*i)
                {
                    data.clear();
                }
                /* POTENTIAL FLAW: Dereference the iterator, which may be invalid if data is cleared */
                cout << " " << *i;
            }
            cout << endl;
        }
    }
}

#endif /* OMITBAD */

#ifndef OMITGOOD

/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */
static void goodB2G1()
{
    list<int>  data;
    if(STATIC_CONST_FIVE==5)
    {
        /* POTENTIAL FLAW: Insert a zero into the list */
        data.push_back(100);
        data.push_back(0);
    }
    if(STATIC_CONST_FIVE!=5)
    {
        /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */
        printLine("Benign, fixed string");
    }
    else
    {
        {
            list<int> ::iterator i;
            cout << "The list contains: ";
            for( i = data.begin(); i != data.end(); i++)
            {
                /* FIX: Do not make any attempt to clear the list */
                cout << " " << *i;
            }
            cout << endl;
        }
    }
}

/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */
static void goodB2G2()
{
    list<int>  data;
    if(STATIC_CONST_FIVE==5)
    {
        /* POTENTIAL FLAW: Insert a zero into the list */
        data.push_back(100);
        data.push_back(0);
    }
    if(STATIC_CONST_FIVE==5)
    {
        {
            list<int> ::iterator i;
            cout << "The list contains: ";
            for( i = data.begin(); i != data.end(); i++)
            {
                /* FIX: Do not make any attempt to clear the list */
                cout << " " << *i;
            }
            cout << endl;
        }
    }
}

/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */
static void goodG2B1()
{
    list<int>  data;
    if(STATIC_CONST_FIVE!=5)
    {
        /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */
        printLine("Benign, fixed string");
    }
    else
    {
        /* FIX: Insert non-zero values into the list */
        data.push_back(100);
        data.push_back(200);
    }
    if(STATIC_CONST_FIVE==5)
    {
        {
            list<int> ::iterator i;
            cout << "The list contains: ";
            for( i = data.begin(); i != data.end(); i++)
            {
                if (!*i)
                {
                    data.clear();
                }
                /* POTENTIAL FLAW: Dereference the iterator, which may be invalid if data is cleared */
                cout << " " << *i;
            }
            cout << endl;
        }
    }
}

/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */
static void goodG2B2()
{
    list<int>  data;
    if(STATIC_CONST_FIVE==5)
    {
        /* FIX: Insert non-zero values into the list */
        data.push_back(100);
        data.push_back(200);
    }
    if(STATIC_CONST_FIVE==5)
    {
        {
            list<int> ::iterator i;
            cout << "The list contains: ";
            for( i = data.begin(); i != data.end(); i++)
            {
                if (!*i)
                {
                    data.clear();
                }
                /* POTENTIAL FLAW: Dereference the iterator, which may be invalid if data is cleared */
                cout << " " << *i;
            }
            cout << endl;
        }
    }
}

void good()
{
    goodB2G1();
    goodB2G2();
    goodG2B1();
    goodG2B2();
}

#endif /* OMITGOOD */

} /* close namespace */

/* Below is the main(). It is only used when building this testcase on
   its own for testing or for building a binary to use in testing binary
   analysis tools. It is not used when compiling all the testcases as one
   application, which is how source code analysis tools are tested. */

#ifdef INCLUDEMAIN

using namespace CWE672_Operation_on_Resource_After_Expiration_or_Release__list_int_06; /* so that we can use good and bad easily */

int main(int argc, char * argv[])
{
    /* seed randomness */
    srand( (unsigned)time(NULL) );
#ifndef OMITGOOD
    printLine("Calling good()...");
    good();
    printLine("Finished good()");
#endif /* OMITGOOD */
#ifndef OMITBAD
    printLine("Calling bad()...");
    bad();
    printLine("Finished bad()");
#endif /* OMITBAD */
    return 0;
}

#endif


text:
package miquilini.felipe.servidor.subsystem.rodada;

import miquilini.felipe.servidor.subsystem.mesa.Jogador;
import miquilini.felipe.servidor.subsystem.mesa.Mesa;

public class RodadaDesempate extends Rodada {
	private final boolean isPrimeira;
	public RodadaDesempate(Mesa mesa, Jogador primeiroJogador, boolean isPrimeira) {
		super(mesa, primeiroJogador);
		this.isPrimeira = isPrimeira;
	}
	@Override
	public void queda(boolean timeAVenceu, boolean timeBVenceu) {
		Mesa mesa = getMesa();
		if(timeAVenceu && timeBVenceu) {
			if(isPrimeira) {
				mesa.novaRodada(new RodadaDesempate(getMesa(), getPrimeiroNaQueda(), false));
			} else {
				//mostrarJogadoresECartas();
				mesa.ninguemVenceu();
				mesa.novaRodada(new RodadaInicial(getMesa(), getPrimeiroNaQueda().getProxJogador()));
			}
		} else if(timeAVenceu) {
			mesa.timeAVence();
			mesa.novaRodada(new RodadaInicial(getMesa(), getPrimeiroNaQueda().getProxJogador()));
			//mostrarJogadoresECartas();
			mesa.addLog("\nTime A venceu a rodada anterior.");
		} else if(timeBVenceu) {
			mesa.timeBVence();
			mesa.novaRodada(new RodadaInicial(getMesa(), getPrimeiroNaQueda().getProxJogador()));
			//mostrarJogadoresECartas();
			mesa.addLog("\nTime B venceu a rodada anterior.");
		} else {
			assert false;
		}
	}

	@Override
	public String toString() {
		return isPrimeira ? "Desempate" : "Segundo Desempate";
	}
}


text:
*{ margin:0px; padding:0px;}
html,body{ font-size:12px;background-color:#FBFBFB; }
.user_main{ width:900px;  margin:auto; }
.memberhead{ width:100%; height:auto; min-height:80px; background:#F3F3F3; border-bottom:2px solid #000033;}
.memberhead1{ width:1000px; height:auto; min-height:80px; margin:auto; position:relative;}
.memberheadlogo{ width:auto; height:auto; float:left; margin:10px 0px 10px 50px;}
.memberheadlogo img{border:0px;}
.memberheadtext{ position:absolute; height:auto; right:50px; bottom:5px; font-size:14px; font-weight:bold; color:#000033;}
.memberheadtext a{ margin:0px 8px 0px 8px; text-decoration:none;color:#000033; }
.memberfoot{ width:900px; margin:auto; height:30px; line-height:30px; font-family:Arial, Helvetica, sans-serif; text-align:center; border-top:1px solid #CCCCCC; }

/*网站地图开始*/
.sitemapweb{ width:900px;  margin:auto; border-left:1px solid #CCCCCC; border-right:1px solid #CCCCCC;}
.sitemapclass{width:95%; height:auto; overflow:auto; margin:auto;}
.sitemapclass1{ margin:8px auto 5px auto; height:auto; line-height:25px; width:95%; text-align:left; border-bottom:1px dashed #CCCCCC; font-weight:bold; }
.sitemapclass1 a{color:#000000;}
.sitemapclass2{ margin:3px 0px 3px 20px; line-height:22px; height:auto; width:auto; float:left; }
.sitemapclass2 a{color:#003399;}
.sitemapclass3{ margin:3px auto 3px auto; height:auto; color:#666666!important; }
.sitemaplist{ width:95%; margin:auto; line-height:25px; text-align:left; position:relative; border-bottom:1px dashed #F4F4F4;}
.sitemaplist span{ width:150px; line-height:20px; text-align:left; position:absolute; right:0px;}
/*网站地图结束*/


text:
//
//  NBMRoomError.h
//  Copyright (c) 2016 Telecom Italia S.p.A. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#import "NBMError.h"

@interface NBMRoomError : NBMError

#ifndef DOXYGEN_SHOULD_SKIP_THIS
// Disallow init and don't add to documentation
- (id)init __attribute__(
                         (unavailable("init is not a supported initializer for this class.")));
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

@end


text:
package com.github.javiersantos.bottomdialogs;

import android.app.Dialog;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.annotation.UiThread;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.res.ResourcesCompat;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class BottomDialog {

    protected final Builder mBuilder;
    protected ImageView vIcon ;
    protected TextView vTitle ;
    protected TextView vContent;
    protected FrameLayout vCustomView;
    protected Button vNegative ;
    protected Button vPositive;

    public final Builder getBuilder() {
        return mBuilder;
    }

    public final ImageView getIconImageView() {
        return vIcon;
    }

    public final TextView getTitleTextView() {
        return vTitle;
    }

    public final TextView getContentTextView() {
        return vContent;
    }

    public final Button getNegativeButton() {
        return vNegative;
    }

    public final Button getPositiveButton() {
        return vPositive;
    }

    protected BottomDialog(Builder builder) {
        mBuilder = builder;
        mBuilder.bottomDialog = initBottomDialog(builder);
    }

    @UiThread
    public void show() {
        if (mBuilder != null && mBuilder.bottomDialog != null)
            mBuilder.bottomDialog.show();
    }

    @UiThread
    public void dismiss() {
        if (mBuilder != null && mBuilder.bottomDialog != null)
            mBuilder.bottomDialog.dismiss();
    }

    @UiThread
    private Dialog initBottomDialog(final Builder builder) {
        final Dialog bottomDialog = new Dialog(builder.context, R.style.BottomDialogs);
        View view = LayoutInflater.from(builder.context).inflate(R.layout.library_bottom_dialog, null);

        vIcon = (ImageView) view.findViewById(R.id.bottomDialog_icon);
        vTitle = (TextView) view.findViewById(R.id.bottomDialog_title);
        vContent = (TextView) view.findViewById(R.id.bottomDialog_content);
        vCustomView = (FrameLayout) view.findViewById(R.id.bottomDialog_custom_view);
        vNegative = (Button) view.findViewById(R.id.bottomDialog_cancel);
        vPositive = (Button) view.findViewById(R.id.bottomDialog_ok);

        if (builder.icon != null) {
            vIcon.setVisibility(View.VISIBLE);
            vIcon.setImageDrawable(builder.icon);
        }

        if (builder.title != null) {
            vTitle.setText(builder.title);
        }

        if (builder.content != null) {
            vContent.setText(builder.content);
        }

        if (builder.customView != null) {
            if (builder.customView.getParent() != null)
                ((ViewGroup) builder.customView.getParent()).removeAllViews();
            vCustomView.addView(builder.customView);
            vCustomView.setPadding(builder.customViewPaddingLeft, builder.customViewPaddingTop, builder.customViewPaddingRight, builder.customViewPaddingBottom);
        }

        if (builder.btn_positive != null) {
            vPositive.setVisibility(View.VISIBLE);
            vPositive.setText(builder.btn_positive);
            vPositive.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (builder.btn_positive_callback != null)
                        builder.btn_positive_callback.onClick(BottomDialog.this);
                    if (builder.isAutoDismiss)
                        bottomDialog.dismiss();
                }
            });

            if (builder.btn_colorPositive != 0) {
                vPositive.setTextColor(builder.btn_colorPositive);
            }

            if (builder.btn_colorPositiveBackground == 0) {
                TypedValue v = new TypedValue();
                boolean hasColorPrimary = builder.context.getTheme().resolveAttribute(R.attr.colorPrimary, v, true);
                builder.btn_colorPositiveBackground = !hasColorPrimary ? v.data : ContextCompat.getColor(builder.context, R.color.colorPrimary);
            }

            Drawable buttonBackground = UtilsLibrary.createButtonBackgroundDrawable(builder.context, builder.btn_colorPositiveBackground);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                vPositive.setBackground(buttonBackground);
            } else {
                // noinspection deprecation
                vPositive.setBackgroundDrawable(buttonBackground);
            }
        }

        if (builder.btn_negative != null) {
            vNegative.setVisibility(View.VISIBLE);
            vNegative.setText(builder.btn_negative);
            vNegative.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (builder.btn_negative_callback != null)
                        builder.btn_negative_callback.onClick(BottomDialog.this);
                    if (builder.isAutoDismiss)
                        bottomDialog.dismiss();
                }
            });

            if (builder.btn_colorNegative != 0) {
                vNegative.setTextColor(builder.btn_colorNegative);
            }
        }

        bottomDialog.setContentView(view);
        bottomDialog.setCancelable(builder.isCancelable);
        bottomDialog.getWindow().setLayout(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        bottomDialog.getWindow().setGravity(Gravity.BOTTOM);

        return bottomDialog;
    }

    public static class Builder {
        protected Context context;

        // Bottom Dialog
        protected Dialog bottomDialog;

        // Icon, Title and Content
        protected Drawable icon;
        protected CharSequence title, content;

        // Buttons
        protected CharSequence btn_negative, btn_positive;
        protected ButtonCallback btn_negative_callback, btn_positive_callback;
        protected boolean isAutoDismiss;

        // Button text colors
        protected int btn_colorNegative, btn_colorPositive;

        // Button background colors
        protected int btn_colorPositiveBackground;

        // Custom View
        protected View customView;
        protected int customViewPaddingLeft, customViewPaddingTop, customViewPaddingRight, customViewPaddingBottom;

        // Other options
        protected boolean isCancelable;

        public Builder(@NonNull Context context) {
            this.context = context;
            this.isCancelable = true;
            this.isAutoDismiss = true;
        }

        public Builder setTitle(@StringRes int titleRes) {
            setTitle(this.context.getString(titleRes));
            return this;
        }

        public Builder setTitle(@NonNull CharSequence title) {
            this.title = title;
            return this;
        }

        public Builder setContent(@StringRes int contentRes) {
            setContent(this.context.getString(contentRes));
            return this;
        }

        public Builder setContent(@NonNull CharSequence content) {
            this.content = content;
            return this;
        }

        public Builder setIcon(@NonNull Drawable icon) {
            this.icon = icon;
            return this;
        }

        public Builder setIcon(@DrawableRes int iconRes) {
            this.icon = ResourcesCompat.getDrawable(context.getResources(), iconRes, null);
            return this;
        }

        public Builder setPositiveBackgroundColorResource(@ColorRes int buttonColorRes) {
            this.btn_colorPositiveBackground = ResourcesCompat.getColor(context.getResources(), buttonColorRes, null);
            return this;
        }

        public Builder setPositiveBackgroundColor(int color) {
            this.btn_colorPositiveBackground = color;
            return this;
        }

        public Builder setPositiveTextColorResource(@ColorRes int textColorRes) {
            this.btn_colorPositive = ResourcesCompat.getColor(context.getResources(), textColorRes, null);
            return this;
        }

        public Builder setPositiveTextColor(int color) {
            this.btn_colorPositive = color;
            return this;
        }

        public Builder setPositiveText(@StringRes int buttonTextRes) {
            setPositiveText(this.context.getString(buttonTextRes));
            return this;
        }

        public Builder setPositiveText(@NonNull CharSequence buttonText) {
            this.btn_positive = buttonText;
            return this;
        }

        public Builder onPositive(@NonNull ButtonCallback buttonCallback) {
            this.btn_positive_callback = buttonCallback;
            return this;
        }

        public Builder setNegativeTextColorResource(@ColorRes int textColorRes) {
            this.btn_colorNegative = ResourcesCompat.getColor(context.getResources(), textColorRes, null);
            return this;
        }

        public Builder setNegativeTextColor(int color) {
            this.btn_colorNegative = color;
            return this;
        }

        public Builder setNegativeText(@StringRes int buttonTextRes) {
            setNegativeText(this.context.getString(buttonTextRes));
            return this;
        }

        public Builder setNegativeText(@NonNull CharSequence buttonText) {
            this.btn_negative = buttonText;
            return this;
        }

        public Builder onNegative(@NonNull ButtonCallback buttonCallback) {
            this.btn_negative_callback = buttonCallback;
            return this;
        }

        public Builder setCancelable(boolean cancelable) {
            this.isCancelable = cancelable;
            return this;
        }

        public Builder autoDismiss(boolean autodismiss) {
            this.isAutoDismiss = autodismiss;
            return this;
        }

        public Builder setCustomView(View customView) {
            this.customView = customView;
            this.customViewPaddingLeft = 0;
            this.customViewPaddingRight = 0;
            this.customViewPaddingTop = 0;
            this.customViewPaddingBottom = 0;
            return this;
        }

        public Builder setCustomView(View customView, int left, int top, int right, int bottom) {
            this.customView = customView;
            this.customViewPaddingLeft = UtilsLibrary.dpToPixels(context, left);
            this.customViewPaddingRight = UtilsLibrary.dpToPixels(context, right);
            this.customViewPaddingTop = UtilsLibrary.dpToPixels(context, top);
            this.customViewPaddingBottom = UtilsLibrary.dpToPixels(context, bottom);
            return this;
        }

        @UiThread
        public BottomDialog build() {
            return new BottomDialog(this);
        }

        @UiThread
        public BottomDialog show() {
            BottomDialog bottomDialog = build();
            bottomDialog.show();
            return bottomDialog;
        }

    }

    public interface ButtonCallback {

        void onClick(@NonNull BottomDialog dialog);
    }

}


text:
define([
    'angular',
    'angular-ui-router'
], function (ng) {
    'use strict';

    return ng.module('app.ships', ['ui.router']);
});


text:
package org.genyris.interp;

import org.genyris.core.Exp;
import org.genyris.core.Internable;
import org.genyris.core.Symbol;
import org.genyris.core.Visitor;
import org.genyris.exception.GenyrisException;

public class EagerProcedure extends AbstractClosure  {
    // I DO evaluate my arguments before being applied.

    public EagerProcedure(Environment env, Exp expression, ApplicableFunction appl) throws GenyrisException {
        super( env,  expression,  appl);
    }

	public Symbol getBuiltinClassSymbol(Internable table) {
		return table.EAGERPROC();
	}

    public Exp[] computeArguments(Environment env, Exp exp) throws GenyrisException {
        Symbol NIL = env.getNil();
        int i = 0;
        Exp[] result = new Exp[exp.length(NIL)];
        while( exp.isPair() ) {
            result[i] = exp.car().eval(env);
            exp = exp.cdr();
            i++;
        }
        return result;
    }

    public void acceptVisitor(Visitor guest) throws GenyrisException {
        guest.visitEagerProc(this);
    }

    public String toString() {
        return "<EagerProc: " + _functionToApply.toString() + ">";
    }

	public Exp eval(Environment env) throws GenyrisException {
		return this;
	}

}


text:
/****************************************************************************
fcoo-application-touch.js

Is adjusted fork of Touch-Menu-Like-Android (https://github.com/ericktatsui/Touch-Menu-Like-Android)

****************************************************************************/

(function ($, window/*, document, undefined*/) {
    "use strict";

    //Create fcoo-namespace
    var ns = window.fcoo = window.fcoo || {};

    var maxMaskOpacity = 0.5; //Equal $modal-backdrop-opacity in \bower_components\bootstrap\scss\_variables.scss

    ns.TouchMenu = function (options) {
        this._onOpen = [];
        this._onClose = [];
        this.isOpen = false;

        this.options = $.extend({
            //Default options
            position     : 'left',
            scroll       : false,  //Only for bottom. left and right are always with scroll expect when having menuOptions for $.bsMMenu
            scrollOptions: null,   //Individuel options for jquery-scroll-container
            modeOver     : false,
            multiMode    : false,
            menuClassName: '',
            isOpen       : false,

            //$menu        : $-element with content (must be inside a <div>), or
            //content      : object with options to create content using $.fn._bsAddHtml
            //createContent: function($container) = function to create the content in $container

            handleClassName    : '',
            $handleContainer   : null,
            allwaysHandle      : false, //When true: Create handle for no-touch browser
            toggleOnHandleClick: false,
            hideHandleWhenOpen : false,

            $neighbourContainer: null,  //$-container that gets resized when the touch-menu is opened/closed

        }, options || {} );

        this.options.verticalMenu    = (this.options.position == 'left') || (this.options.position == 'right');
        this.options.scroll          = this.options.scroll || (this.options.verticalMenu && !this.options.menuOptions);
        this.options.directionFactor = (this.options.position == 'left') || (this.options.position == 'top') ? 1 : -1;

        if (this.options.verticalMenu){
            this.options.openDirection  = this.options.position == 'left' ? 'right' : 'left';
            this.options.closeDirection = this.options.position;
        }
        else {
            this.options.openDirection  = this.options.position == 'top' ? 'down' : 'up';
            this.options.closeDirection = this.options.position == 'top' ? 'up' : 'down';
        }

        if (this.options.$neighbourContainer)
            this.options.$neighbourContainer.addClass('neighbour-container');

        //Initialize the menu
        this.$container = this.options.$container ? this.options.$container : $('<div/>');
        this.$container
            .addClass('touch-menu-container')
            .addClass( $._bsGetSizeClass({baseClass: 'touch-menu-container', useTouchSize: true}) )
            .addClass(this.options.position)
            .addClass(this.options.menuClassName);

        //If the dimention is 'auto' add on-resize event to update width/height
        if (this.options[ this.options.verticalMenu ? 'width' : 'height' ] == 'auto'){
            this.$container
                .addClass(this.options.verticalMenu ? 'vertical-auto-width' : 'vertical-auto-height')
                .resize( $.proxy( this.onResize, this) );
        }

        this.setMode( this.options.modeOver );

        this.isPanning = false;
        this.onlyScroll = false;

        //Create container for the contents
        if (this.options.$preMenu || this.options.inclPreMenu || this.options.preMenuClassName || this.options.$postMenu || this.options.inclPostMenu || this.options.postMenuClassName){

            //Change container to flex-display
            this.$container.addClass('d-flex');
            this.$container.addClass(this.options.verticalMenu ? 'flex-column' : 'flex-row');

            if (this.options.$preMenu || this.options.inclPreMenu || this.options.preMenuClassName){
                this.$preMenu = this.options.$preMenu ? this.options.$preMenu : $('<div/>');
                this.$preMenu
                    .addClass('touch-pre-menu flex-shrink-0')
                    .addClass(this.options.preMenuClassName)
                    .appendTo(this.$container);
            }

            var $menuContainer = $('<div/>')
                .addClass('touch-menu flex-grow-1 flex-shrink-1')
                .appendTo(this.$container);

                if (this.options.scroll)
                    this.$menu = $menuContainer.addScrollbar( this.options.scrollOptions );
                else
                    this.$menu = $menuContainer;

            //Create the bottom/right part
            if (this.options.$postMenu || this.options.inclPostMenu || this.options.postMenuClassName){
                this.$postMenu = this.options.$postMenu ? this.options.$postMenu : $('<div/>');
                this.$postMenu
                    .addClass('touch-post-menu flex-shrink-0')
                    .addClass(this.options.postMenuClassName)
                    .appendTo(this.$container);
            }
        }
        else
            this.$menu = this.$container;

        //Move or create any content into the menu
        if (this.options.$menu)
            this.options.$menu.contents().detach().appendTo(this.$menu);
        else
            if (this.options.content)
                this.$menu._bsAddHtml(this.options.content);
            else
                if (this.options.createContent)
                    this.options.createContent(this.$menu);

        if (window.bsIsTouch)
            //Add events to container
            this._add_swiped(this.$container);

        //Create the handle
        if (this.options.standardHandler){
            this.options = $.extend(this.options, {
                handleWidth        : 3*16,
                handleClassName    : 'horizontal-bar fas fa-minus',
                toggleOnHandleClick: true,
                hideHandleWhenOpen : true
            });
        }

        if (window.bsIsTouch || this.options.allwaysHandle || this.options.toggleOnHandleClick){
            this.$handle = this.options.$handle ? this.options.$handle : $('<div/>');
            this.$handle
                .addClass('touch-menu-handle')
                .toggleClass(this.options.position, !!this.options.$handleContainer)
                .addClass(this.options.handleClassName)
                .toggleClass('hide-when-open', this.options.hideHandleWhenOpen)

                .appendTo(this.options.$handleContainer ? this.options.$handleContainer : this.$container);

            if (this.options.$handleContainer)
                //Add events on handle outside the menu
                this._add_swiped(this.$handle);

            if (this.options.toggleOnHandleClick)
                this.$handle.on('click', $.proxy(this.toggle, this));
        }

        //Update dimention and size of the menu and handle
        this.updateDimentionAndSize();

        //Craete the mask
        if (this.options.modeOver || this.options.multiMode) {
            this.$mask =
                $('<div/>')
                .addClass('touch-menu-mask')
                .appendTo('body');

            if (window.bsIsTouch)
                //Add events to mask
                this._add_swiped(this.$mask);

            this.$mask.on('click', $.proxy(this.close, this));
        }

        //Create the $.bsMenu if menuOptions are given
        if (this.options.menuOptions)
            this.mmenu = ns.createMmenu(this.options.position, this.options.menuOptions, this.$menu);

        if (this.options.isOpen)
            this.open(true);
        else
            this.close(true);
    };

    /******************************************
    Extend the prototype
    ******************************************/
    ns.TouchMenu.prototype = {
        _add_swiped: function($element){
            this._this_open  = this._this_open  || $.proxy(this.open,  this);
            this._this_close = this._this_close || $.proxy(this.close, this);
            $element
                .on('swiped-' + this.options.openDirection,  this._this_open  )
                .on('swiped-' + this.options.closeDirection, this._this_close );

            return $element;
        },

        onResize: function(){
            var dim = this.options.verticalMenu ? this.$container.outerWidth() : this.$container.outerHeight();

            this.options[this.options.verticalMenu ? 'width' : 'height'] = dim;

            this.updateDimentionAndSize();

            this.animateToPosition(dim, false, true);

            this.changeNeighbourContainerPos(this.isOpen ? dim : 0, false);
        },

        updateDimentionAndSize: function(){
            var _this = this,
                cssDimensionId = this.options.verticalMenu ? 'height' : 'width',
                cssPosId       = this.options.verticalMenu ? 'top'    : 'left',
                cssPositionId;
            switch (this.options.position){
                case 'left'  : cssPositionId = 'right';  break;
                case 'right' : cssPositionId = 'left';   break;
                case 'top'   : cssPositionId = 'bottom'; break;
                case 'bottom': cssPositionId = 'top';    break;
            }

            //*********************************************************************
            function getDimensionAndSize( width, height, defaultSize ){
                var result =
                    _this.options.verticalMenu ? {
                        dimension: height || 0,
                        size     : width  || defaultSize
                    } : {
                        dimension: width || 0,
                        size     : height || defaultSize
                    };
                result.halfDimension = result.dimension/2;
                result.halfSize = result.size/2;
                return result;
            }
            //*********************************************************************
            function setElementDimensionAndSize( $elem, options ){
                //Set width (top/bottom) or height (left/right) of menu and center if not 100%
                if (options.dimension)
                    $elem
                        .css(cssDimensionId, options.dimension + 'px')
                        .css(cssPosId, '50%')
                        .css(_this.options.verticalMenu ? 'margin-top' : 'margin-left', -1*options.halfDimension);
                else
                    $elem
                        .css(cssDimensionId, '100%')
                        .css(cssPosId,   '0px');

                $elem.css(_this.options.verticalMenu ? 'width' : 'height', options.size);
                return $elem;
            }
            //*********************************************************************

            this.options.menuDimAndSize   = getDimensionAndSize( this.options.width,       this.options.height,       280 );
            this.options.handleDimAndSize = getDimensionAndSize( this.options.handleWidth, this.options.handleHeight,  20 );

            //Update the menu-element
            this.$container.css(this.options.position, -1*this.options.menuDimAndSize.size + 'px');
            //Set width (top/bottom) or height (left/right) of menu and center if not 100%
            setElementDimensionAndSize(this.$container, this.options.menuDimAndSize);

            if (this.$handle){
                if (!this.options.$handleContainer)
                    this.$handle.css(cssPositionId, -1*this.options.handleDimAndSize.size + 'px');

                //Set width (top/bottom) or height (left/right) of menu and center if not 100%
                setElementDimensionAndSize(this.$handle, this.options.handleDimAndSize);
            }
        },

        setMode: function( over ){
            var isOpen = this.isOpen;
            if (isOpen)
                this.close(true);

            this.options.modeOver = !!over;

            this.$container.removeClass('mode-over mode-side');
            this.$container.addClass(this.options.modeOver ? 'mode-over' : 'mode-side');

            if (isOpen)
                this.open(true);
        },

        _copyClassName: function(){
            //Sets the class-name of this.$handle equal to this.$container if the handle is outrside the container
            var _this = this;
            $.each(['closed', 'opening', 'opened', 'closing'], function(index, className){
                var hasClass = _this.$container.hasClass(className);
                if (_this.$handle)
                    _this.$handle.toggleClass(className, hasClass);
                if (_this.$mask)
                    _this.$mask.toggleClass(className, hasClass);
            });
        },

        animateToPosition: function (pos, animateMain, noAnimation) {
            this.$container.toggleClass('no-animation', !!noAnimation);

            if (this.options.verticalMenu)
                this.$container.css('transform', 'translate3d(' + this.options.directionFactor*pos + 'px, 0, 0)');
            else
                this.$container.css('transform', 'translate3d(0, ' + this.options.directionFactor*pos + 'px, 0)');

            this.changeNeighbourContainerPos(pos, animateMain && !noAnimation);
        },

        changeNeighbourContainerPos: function( pos, animate ){
            if (this.options.$neighbourContainer && !this.options.modeOver)
                this.options.$neighbourContainer
                    .toggleClass('no-animation', !animate)
                    .css('margin-'+this.options.position, Math.max(0,pos)+'px');
        },

        setMaskOpacity: function (newMenuPos) {
            this._setMaskOpacity( parseFloat((newMenuPos / this.options.menuDimAndSize.size) * maxMaskOpacity) );
        },

        _setMaskOpacity: function (opacity) {
            if (this.$mask)
                    this.$mask
                        .css('opacity', opacity)
                        .toggleClass('visible', !!(this.options.modeOver && opacity));
        },

        showMask: function () {
            this._setMaskOpacity(maxMaskOpacity);
        },

        hideMask: function () {
            this._setMaskOpacity(0);
        },

        _invoke: function (fn) {
            if (fn)
                fn.apply(this);
        },

        _onOpen: [],

        open: function (noAnimation) {
            var _this = this;
            this.$container.addClass('opened').removeClass('opening closing closed');
            this._copyClassName();

            this.animateToPosition(this.options.menuDimAndSize.size, true, noAnimation);

            this.isOpen = true;

            this.$container.removeClass('no-animation');

            this.showMask();
            $.each(this._onOpen, function(index, func){
                func(_this);
            });

            this._invoke(this.options.onOpen);
        },

        _onClose: [],

        close: function (noAnimation) {
            var _this = this;
            this.$container.addClass('closed').removeClass('opening closing opened');
            this._copyClassName();

            this.changeNeighbourContainerPos(0, !noAnimation);

            this.isOpen = false;
            this.hideMask();

            $.each(this._onClose, function(index, func){
                func(_this);
            });

            this._invoke(this.options.onClose);
        },

        toggle: function () {
            if (this.isOpen)
                this.close();
            else
                this.open();
        },

    };

    ns.touchMenu = function(options){
        return new ns.TouchMenu(options);
    };

}(jQuery, this, document));


text:
'use strict';

var json2csv = require('nice-json2csv');
var utils    = require('../utils');
var config   = require('../config');

/**
 * Checks if value is undefined and returns defValue. Othervise value is returned
 * @param {*} value - Value to check.
 * @param {*} defValue - Default value to be returned in value is undefined.
 * @returns {*} defValue if value it undefined, otherwise return value
 */
function undefCheck(value, defValue) {
	if(typeof value === 'undefined' || value == '') {return defValue}
	return value;
}
/**
 * Return hex color to readable format
 * @param {string} hex - Hex value to be turned.
 * @returns {string} color hex converted
 */
function hexToColor(hex) {
	if(hex === '#724a7f') {return 'purple';}
	if(hex === '#eb584a') {return 'red';}
	if(hex === '#dcc75b') {return 'yellow';}
	if(hex === '#4f819a') {return 'blue';}
	return "";
}

/**
 * Edits content text to be on same line
 * @param {string} content - content to be edited.
 * @returns {string} content edited
 */
function contentEdit(content) {
	content = content.replace(/\n/g, '\n          ');
	// Replace markdown symbols with something a bit more sensible
	content = content.replace(/[\)#_*~`\]\[]/g, '').replace(/\(/g, ':');
	return content;
}

function addCommentsToTicket(tickets, comments) {
	return tickets.map(function(ticket) {
		ticket.comments = comments.filter(function(comment){
			return ticket._id.equals(comment.data.ticket_id);
		}).map(function(comment) {
			return { user: comment.user.name, message: comment.data.message };
		});
		delete ticket._id;
		return ticket;
	});
}

/**
 * Generates plain text from board and tickets
 * @param {object} board - Board object to be generated.
 * @param {object} tickets - Tickets to be generated.
 * @returns {string} plain text
 */
function generatePlainText(board, tickets) {
		return 'Board information\n' +
		'=========================================\n\n' +
		'Board name: ' + undefCheck(board.name, '') + '\n\n' +
		'Board members: \n' +
		board.members.map(function(member){
			return '    ' + member.user.name + ' - ' + member.role + '\n'
		}).join('') + '\n' +
		'=========================================\n\n\n\n' +
		'Tickets information\n' +
		'=========================================\n' +
		tickets.map(function(t) {
			return '\n' +
				'------------------------------------------\n' +
				'Heading:  ' + contentEdit(undefCheck(t.heading, 'Empty')) + '\n\n' +
				'Content:  ' + contentEdit(undefCheck(t.content, 'Empty')) + '\n\n' +
				'Color:    ' + hexToColor(t.color) + '\n\n' +
				'Comments: ' + undefCheck(t.comments.map(function(c) {return '\n      ' + c.user + ': ' + c.message}).join(''), 'None') + '\n' +
				'------------------------------------------\n';
		}).join('') + '\n' +
		'=========================================';
}

/**
 * Generates CSV from board and tickets
 * @param {object} board - Board object to be generated.
 * @param {object} tickets - Tickets to be generated.
 * @returns {string} csv text
 */
function generateCSV(board, tickets) {
	var membersCSVData = board.members.map(function(member){
		return {
			'MEMBER': member.user.name,
			'ROLE': member.role
		};
	});

	var boardCSVData = {
		'NAME':        board.name,
		'DESCRIPTION': board.description,
		'SIZE_WIDTH':  '' + board.size.width  + '',
		'SIZE_HEIGHT': '' + board.size.height + '',
	}

	var ticketCSVData = tickets.map(function(t) {
		return {
			'HEADING':    t.heading,
			'CONTENT':    t.content,
			'COLOR':      t.color,
			'COMMENTS':   t.comments.map(function(c) {
				return c.user + ': ' + c.message;
			}) + '',
			'POSITION_X': '' + t.position.x + '',
			'POSITION_Y': '' + t.position.y + '',
			'POSITION_Z': '' + t.position.z + '',
		}
	});
	var csvMembers  = json2csv.convert(membersCSVData);
	var csvBoard    = json2csv.convert(boardCSVData);
	var csvTickets  = json2csv.convert(ticketCSVData);
	return csvBoard + '\n\n' + csvMembers + '\n\n' + csvTickets;
}

/**
 * Defines data and options posted to image service
 * @param {object} board - Board object to be generated.
 * @param {object} tickets - Tickets to be generated.
 * @returns {string} callback to post method
 */

function postImage(req, board, tickets, callback) {
	if(tickets == null)
		var tickets = [];

	var postData = {
		'name': board.name,
		'background': board.background,
		'customBackground': board.customBackground,
		'size': {
			'height': board.size.height,
			'width': board.size.width
		},
		'tickets': tickets
	};

	var options = {
		url: config.img + '/board',
		method: 'POST',
		form: postData,
		headers: {
			'Content-Type': 'application/json'
		}
	};

	return callback(options);
};

module.exports = {
	generatePlainText: 	 generatePlainText,
	generateCSV: 		 generateCSV,
	postImage: 			 postImage,
	addCommentsToTicket: addCommentsToTicket
}


text:
package ru.job4j;

public abstract class StackQueueContainer<E> {
    protected SimpleLinkList<E> simpleLinkList;

    public StackQueueContainer() {
        this.simpleLinkList = new SimpleLinkList<>();
    }

    public abstract E poll();

    public void push(E value) {
        if (simpleLinkList.getSize() > 0) {
            simpleLinkList.add(simpleLinkList.get(simpleLinkList.getSize() - 1));
            if (simpleLinkList.getSize() > 2) {
                for (int i = simpleLinkList.getSize() - 2; i > 0; i--) {
                    simpleLinkList.set(i, simpleLinkList.get(i - 1));
                }
            }
            simpleLinkList.set(0, value);
        } else {
            simpleLinkList.add(value);
        }
    }
}


text:
require 'rails_helper'

RSpec.describe Spree::LineItem, type: :model do
  let(:order) { create :order_with_line_items, line_items_count: 1 }
  let(:line_item) { order.line_items.first }

  context '#destroy' do
    it "fetches soft-deleted products" do
      line_item.product.discard
      expect(line_item.reload.product).to be_a Spree::Product
    end

    it "fetches soft-deleted variants" do
      line_item.variant.discard
      expect(line_item.reload.variant).to be_a Spree::Variant
    end

    it "returns inventory when a line item is destroyed" do
      expect_any_instance_of(Spree::OrderInventory).to receive(:verify)
      line_item.destroy
    end

    it "deletes inventory units" do
      expect { line_item.destroy }.to change { line_item.inventory_units.count }.from(1).to(0)
    end
  end

  context "#save" do
    context "target_shipment is provided" do
      it "verifies inventory" do
        line_item.target_shipment = Spree::Shipment.new
        expect_any_instance_of(Spree::OrderInventory).to receive(:verify)
        line_item.save
      end
    end
  end

  describe 'line item creation' do
    let(:variant) { create :variant }

    subject(:line_item) { Spree::LineItem.new(variant: variant, order: order) }

    # Tests for https://github.com/spree/spree/issues/3391
    context 'before validation' do
      before { line_item.valid? }

      it 'copies the variants price' do
        expect(line_item.price).to eq(variant.price)
      end

      it 'copies the variants cost_price' do
        expect(line_item.cost_price).to eq(variant.cost_price)
      end

      it "copies the order's currency" do
        expect(line_item.currency).to eq(order.currency)
      end

      # Test for https://github.com/spree/spree/issues/3481
      it 'copies the variants tax category' do
        expect(line_item.tax_category).to eq(line_item.variant.tax_category)
      end
    end

    # Specs for https://github.com/solidusio/solidus/pull/522#issuecomment-170668125
    context "with `#copy_price` defined" do
      before(:context) do
        Spree::LineItem.class_eval do
          def copy_price
            self.cost_price = 10
            self.price = 20
          end
        end
      end

      after(:context) do
        Spree::LineItem.class_eval do
          remove_method :copy_price
        end
      end

      it 'should display a deprecation warning' do
        expect(Spree::Deprecation).to receive(:warn)
        Spree::LineItem.new(variant: variant, order: order)
      end

      it 'should run the user-defined copy_price method' do
        expect_any_instance_of(Spree::LineItem).to receive(:copy_price).and_call_original
        Spree::Deprecation.silence do
          Spree::LineItem.new(variant: variant, order: order)
        end
      end
    end
  end

  # TODO: Remove this spec after the method has been removed.
  describe '#discounted_amount' do
    it "returns the amount minus any discounts" do
      line_item.price = 10
      line_item.quantity = 2
      line_item.promo_total = -5
      expect(Spree::Deprecation.silence { line_item.discounted_amount }).to eq(15)
    end
  end

  # TODO: Remove this spec after the method has been removed.
  describe "#discounted_money" do
    it "should return a money object with the discounted amount" do
      expect(Spree::Deprecation.silence { line_item.discounted_amount }).to eq(10.00)
      expect(Spree::Deprecation.silence { line_item.discounted_money.to_s }).to eq "$10.00"
    end
  end

  describe '#total_before_tax' do
    before do
      line_item.update!(price: 10, quantity: 2)
    end
    let!(:admin_adjustment) { create(:adjustment, adjustable: line_item, order: line_item.order, amount: -1, source: nil) }
    let!(:promo_adjustment) { create(:adjustment, adjustable: line_item, order: line_item.order, amount: -2, source: promo_action) }
    let!(:ineligible_promo_adjustment) { create(:adjustment, eligible: false, adjustable: line_item, order: line_item.order, amount: -4, source: promo_action) }
    let(:promo_action) { promo.actions[0] }
    let(:promo) { create(:promotion, :with_line_item_adjustment) }

    it 'returns the amount minus any adjustments' do
      expect(line_item.total_before_tax).to eq(20 - 1 - 2)
    end
  end

  describe ".money" do
    before do
      line_item.price = 3.50
      line_item.quantity = 2
    end

    it "returns a Spree::Money representing the total for this line item" do
      expect(line_item.money.to_s).to eq("$7.00")
    end
  end

  describe '.single_money' do
    before { line_item.price = 3.50 }
    it "returns a Spree::Money representing the price for one variant" do
      expect(line_item.single_money.to_s).to eq("$3.50")
    end
  end

  context 'setting a line item price' do
    let(:store) { create(:store, default: true) }
    let(:order) { Spree::Order.new(currency: "RUB", store: store) }
    let(:variant) { Spree::Variant.new(product: Spree::Product.new) }
    let(:line_item) { Spree::LineItem.new(order: order, variant: variant) }

    before { expect(variant).to receive(:price_for).at_least(:once).and_return(price) }

    context "when a price exists in order currency" do
      let(:price) { Spree::Money.new(99.00, currency: "RUB") }

      it "is a valid line item" do
        expect(line_item.valid?).to be_truthy
        expect(line_item.errors[:price].size).to eq(0)
      end
    end

    context "when a price does not exist in order currency" do
      let(:price) { nil }

      it "is not a valid line item" do
        expect(line_item.valid?).to be_falsey
        expect(line_item.errors[:price].size).to eq(1)
      end
    end
  end

  describe "#options=" do
    let(:options) { { price: 123, quantity: 5 } }

    it "updates the data provided in the options" do
      line_item.options = options

      expect(line_item.price).to eq 123
      expect(line_item.quantity).to eq 5
    end

    context "when price is not provided" do
      let(:options) { { quantity: 5 } }

      it "sets price anyway, retrieving it from line item options" do
        expect(line_item.variant)
          .to receive(:price_for)
          .and_return(Spree::Money.new(123, currency: "USD"))

        line_item.options = options

        expect(line_item.price).to eq 123
        expect(line_item.quantity).to eq 5
      end
    end
  end

  describe 'money_price=' do
    let(:currency) { "USD" }
    let(:new_price) { Spree::Money.new(99.00, currency: currency) }

    it 'assigns a new price' do
      line_item.money_price = new_price
      expect(line_item.price).to eq(new_price.cents / 100.0)
    end

    context 'when the new price is nil' do
      let(:new_price) { nil }

      it 'makes the line item price empty' do
        line_item.money_price = new_price
        expect(line_item.price).to be_nil
      end
    end

    context 'when the price has a currency different from the order currency' do
      let(:currency) { "RUB" }

      before do
        stub_spree_preferences(raise_with_invalid_currency: raise_with_invalid_currency)
      end

      context 'when raise_with_invalid_currency preference is true' do
        let(:raise_with_invalid_currency) { true }

        it 'raises an exception' do
          expect {
            line_item.money_price = new_price
          }.to raise_exception(
            Spree::LineItem::CurrencyMismatch,
            'Line item price currency must match order currency!'
          )
        end
      end

      context 'when raise_with_invalid_currency preference is false' do
        let(:raise_with_invalid_currency) { false }

        it 'is not valid' do
          line_item.money_price = new_price
          expect(line_item).not_to be_valid
          expect(line_item.errors[:price])
            .to include 'Line item price currency must match order currency!'
        end
      end
    end
  end

  describe "#pricing_options" do
    subject { line_item.pricing_options }

    it { is_expected.to be_a(Spree::Config.pricing_options_class) }

    it "holds the order currency" do
      expect(subject.currency).to eq("USD")
    end
  end
end