text:
As the first four chapters of this book were all about performance as a coding pattern (asynchrony and concurrency), and Chapter 5 was about performance at the macro program architecture level, this chapter goes after the topic of performance at the micro level, focusing on single expressions/statements.

One of the most common areas of curiosity -- indeed, some developers can get quite obsessed about it -- is in analyzing and testing various options for how to write a line or chunk of code, and which one is faster.

We're going to look at some of these issues, but it's important to understand from the outset that this chapter is **not** about feeding the obsession of micro-performance tuning, like whether some given JS engine can run `++a` faster than `a++`. The more important goal of this chapter is to figure out what kinds of JS performance matter and which ones don't, *and how to tell the difference*.

But even before we get there, we need to explore how to most accurately and reliably test JS performance, because there's tons of misconceptions and myths that have flooded our collective cult knowledge base. We've got to sift through all that junk to find some clarity.

## Benchmarking

OK, time to start dispelling some misconceptions. I'd wager the vast majority of JS developers, if asked to benchmark the speed (execution time) of a certain operation, would initially go about it something like this:

```js
var start = (new Date()).getTime();	// or `Date.now()`

// do some operation

var end = (new Date()).getTime();

console.log( "Duration:", (end - start) );
```

Raise your hand if that's roughly what came to your mind. Yep, I thought so. There's a lot wrong with this approach, but don't feel bad; **we've all been there.**

What did that measurement tell you, exactly? Understanding what it does and doesn't say about the execution time of the operation in question is key to learning how to appropriately benchmark performance in JavaScript.

If the duration reported is `0`, you may be tempted to believe that it took less than a millisecond. But that's not very accurate. Some platforms don't have single millisecond precision, but instead only update the timer in larger increments. For example, older versions of windows (and thus IE) had only 15ms precision, which means the operation has to take at least that long for anything other than `0` to be reported!

Moreover, whatever duration is reported, the only thing you really know is that the operation took approximately that long on that exact single run. You have near-zero confidence that it will always run at that speed. You have no idea if the engine or system had some sort of interference at that exact moment, and that at other times the operation could run faster.

What if the duration reported is `4`? Are you more sure it took about four milliseconds? Nope. It might have taken less time, and there may have been some other delay in getting either `start` or `end` timestamps.

More troublingly, you also don't know that the circumstances of this operation test aren't overly optimistic. It's possible that the JS engine figured out a way to optimize your isolated test case, but in a more real program such optimization would be diluted or impossible, such that the operation would run slower than your test.

So... what do we know? Unfortunately, with those realizations stated, **we know very little.** Something of such low confidence isn't even remotely good enough to build your determinations on. Your "benchmark" is basically useless. And worse, it's dangerous in that it implies false confidence, not just to you but also to others who don't think critically about the conditions that led to those results.

### Repetition

"OK," you now say, "Just put a loop around it so the whole test takes longer." If you repeat an operation 100 times, and that whole loop reportedly takes a total of 137ms, then you can just divide by 100 and get an average duration of 1.37ms for each operation, right?

Well, not exactly.

A straight mathematical average by itself is definitely not sufficient for making judgments about performance which you plan to extrapolate to the breadth of your entire application. With a hundred iterations, even a couple of outliers (high or low) can skew the average, and then when you apply that conclusion repeatedly, you even further inflate the skew beyond credulity.

Instead of just running for a fixed number of iterations, you can instead choose to run the loop of tests until a certain amount of time has passed. That might be more reliable, but how do you decide how long to run? You might guess that it should be some multiple of how long your operation should take to run once. Wrong.

Actually, the length of time to repeat across should be based on the accuracy of the timer you're using, specifically to minimize the chances of inaccuracy. The less precise your timer, the longer you need to run to make sure you've minimized the error percentage. A 15ms timer is pretty bad for accurate benchmarking; to minimize its uncertainty (aka "error rate") to less than 1%, you need to run your each cycle of test iterations for 750ms. A 1ms timer only needs a cycle to run for 50ms to get the same confidence.

But then, that's just a single sample. To be sure you're factoring out the skew, you'll want lots of samples to average across. You'll also want to understand something about just how slow the worst sample is, how fast the best sample is, how far apart those best and worse cases were, and so on. You'll want to know not just a number that tells you how fast something ran, but also to have some quantifiable measure of how trustable that number is.

Also, you probably want to combine these different techniques (as well as others), so that you get the best balance of all the possible approaches.

That's all bare minimum just to get started. If you've been approaching performance benchmarking with anything less serious than what I just glossed over, well... "you don't know: proper benchmarking."

### Benchmark.js

Any relevant and reliable benchmark should be based on statistically sound practices. I am not going to write a chapter on statistics here, so I'll hand wave around some terms: standard deviation, variance, margin of error. If you don't know what those terms really mean -- I took a stats class back in college and I'm still a little fuzzy on them -- you are not actually qualified to write your own benchmarking logic.

Luckily, smart folks like John-David Dalton and Mathias Bynens do understand these concepts, and wrote a statistically sound benchmarking tool called Benchmark.js (http://benchmarkjs.com/). So I can end the suspense by simply saying: "just use that tool."

I won't repeat their whole documentation for how Benchmark.js works; they have fantastic API Docs (http://benchmarkjs.com/docs) you should read. Also there are some great (http://calendar.perfplanet.com/2010/bulletproof-javascript-benchmarks/) writeups (http://monsur.hossa.in/2012/12/11/benchmarkjs.html) on more of the details and methodology.

But just for quick illustration purposes, here's how you could use Benchmark.js to run a quick performance test:

```js
function foo() {
	// operation(s) to test
}

var bench = new Benchmark(
	"foo test",				// test name
	foo,					// function to test (just contents)
	{
		// ..				// optional extra options (see docs)
	}
);

bench.hz;					// number of operations per second
bench.stats.moe;			// margin of error
bench.stats.variance;		// variance across samples
// ..
```

There's *lots* more to learn about using Benchmark.js besides this glance I'm including here. But the point is that it's handling all of the complexities of setting up a fair, reliable, and valid performance benchmark for a given piece of JavaScript code. If you're going to try to test and benchmark your code, this library is the first place you should turn.

We're showing here the usage to test a single operation like X, but it's fairly common that you want to compare X to Y. This is easy to do by simply setting up two different tests in a "Suite" (a Benchmark.js organizational feature). Then, you run them head-to-head, and compare the statistics to conclude whether X or Y was faster.

Benchmark.js can of course be used to test JavaScript in a browser (see the "jsPerf.com" section later in this chapter), but it can also run in non-browser environments (Node.js, etc.).

One largely untapped potential use-case for Benchmark.js is to use it in your Dev or QA environments to run automated performance regression tests against critical path parts of your application's JavaScript. Similar to how you might run unit test suites before deployment, you can also compare the performance against previous benchmarks to monitor if you are improving or degrading application performance.

#### Setup/Teardown

In the previous code snippet, we glossed over the "extra options" `{ .. }` object. But there are two options we should discuss: `setup` and `teardown`.

These two options let you define functions to be called before and after your test case runs.

It's incredibly important to understand that your `setup` and `teardown` code **does not run for each test iteration**. The best way to think about it is that there's an outer loop (repeating cycles), and an inner loop (repeating test iterations). `setup` and `teardown` are run at the beginning and end of each *outer* loop (aka cycle) iteration, but not inside the inner loop.

Why does this matter? Let's imagine you have a test case that looks like this:

```js
a = a + "w";
b = a.charAt( 1 );
```

Then, you set up your test `setup` as follows:

```js
var a = "x";
```

Your temptation is probably to believe that `a` is starting out as `"x"` for each test iteration.

But it's not! It's starting `a` at `"x"` for each test cycle, and then your repeated `+ "w"` concatenations will be making a larger and larger `a` value, even though you're only ever accessing the character `"w"` at the `1` position.

Where this most commonly bites you is when you make side effect changes to something like the DOM, like appending a child element. You may think your parent element is set as empty each time, but it's actually getting lots of elements added, and that can significantly sway the results of your tests.

## Context Is King

Don't forget to check the context of a particular performance benchmark, especially a comparison between X and Y tasks. Just because your test reveals that X is faster than Y doesn't mean that the conclusion "X is faster than Y" is actually relevant.

For example, let's say a performance test reveals that X runs 10,000,000 operations per second, and Y runs at 8,000,000 operations per second. You could claim that Y is 20% slower than X, and you'd be mathematically correct, but your assertion doesn't hold as much water as you'd think.

Let's think about the results more critically: 10,000,000 operations per second is 10,000 operations per millisecond, and 10 operations per microsecond. In other words, a single operation takes 0.1 microseconds, or 100 nanoseconds. It's hard to fathom just how small 100ns is, but for comparison, it's often cited that the human eye isn't generally capable of distinguishing anything less than 100ms, which is one million times slower than the 100ns speed of the X operation.

Even recent scientific studies showing that maybe the brain can process as quick as 13ms (about 8x faster than previously asserted) would mean that X is still running 125,000 times faster than the human brain can perceive a distinct thing happening. **X is going really, really fast.**

But more importantly, let's talk about the difference between X and Y, the 2,000,000 operations per second difference. If X takes 100ns, and Y takes 80ns, the difference is 20ns, which in the best case is still one 650-thousandth of the interval the human brain can perceive.

What's my point? **None of this performance difference matters, at all!**

But wait, what if this operation is going to happen a whole bunch of times in a row? Then the difference could add up, right?

OK, so what we're asking then is, how likely is it that operation X is going to be run over and over again, one right after the other, and that this has to happen 650,000 times just to get a sliver of a hope the human brain could perceive it. More likely, it'd have to happen 5,000,000 to 10,000,000 times together in a tight loop to even approach relevance.

While the computer scientist in you might protest that this is possible, the louder voice of realism in you should sanity check just how likely or unlikely that really is. Even if it is relevant in rare occasions, it's irrelevant in most situations.

The vast majority of your benchmark results on tiny operations -- like the `++x` vs `x++` myth -- **are just totally bogus** for supporting the conclusion that X should be favored over Y on a performance basis.

### Engine Optimizations

You simply cannot reliably extrapolate that if X was 10 microseconds faster than Y in your isolated test, that means X is always faster than Y and should always be used. That's not how performance works. It's vastly more complicated.

For example, let's imagine (purely hypothetical) that you test some microperformance behavior such as comparing:

```js
var twelve = "12";
var foo = "foo";

// test 1
var X1 = parseInt( twelve );
var X2 = parseInt( foo );

// test 2
var Y1 = Number( twelve );
var Y2 = Number( foo );
```

If you understand what `parseInt(..)` does compared to `Number(..)`, you might intuit that `parseInt(..)` potentially has "more work" to do, especially in the `foo` case. Or you might intuit that they should have the same amount of work to do in the `foo` case, as both should be able to stop at the first character `"f"`.

Which intuition is correct? I honestly don't know. But I'll make the case it doesn't matter what your intuition is. What might the results be when you test it? Again, I'm making up a pure hypothetical here, I haven't actually tried, nor do I care.

Let's pretend the test comes back that `X` and `Y` are statistically identical. Have you then confirmed your intuition about the `"f"` character thing? Nope.

It's possible in our hypothetical that the engine might recognize that the variables `twelve` and `foo` are only being used in one place in each test, and so it might decide to inline those values. Then it may realize that `Number( "12" )` can just be replaced by `12`. And maybe it comes to the same conclusion with `parseInt(..)`, or maybe not.

Or an engine's dead-code removal heuristic could kick in, and it could realize that variables `X` and `Y` aren't being used, so declaring them is irrelevant, so it doesn't end up doing anything at all in either test.

And all that's just made with the mindset of assumptions about a single test run. Modern engines are fantastically more complicated than what we're intuiting here. They do all sorts of tricks, like tracing and tracking how a piece of code behaves over a short period of time, or with a particularly constrained set of inputs.

What if the engine optimizes a certain way because of the fixed input, but in your real program you give more varied input and the optimization decisions shake out differently (or not at all!)? Or what if the engine kicks in optimizations because it sees the code being run tens of thousands of times by the benchmarking utility, but in your real program it will only run a hundred times in near proximity, and under those conditions the engine determines the optimizations are not worth it?

And all those optimizations we just hypothesized about might happen in our constrained test but maybe the engine wouldn't do them in a more complex program (for various reasons). Or it could be reversed -- the engine might not optimize such trivial code but may be more inclined to optimize it more aggressively when the system is already more taxed by a more sophisticated program.

The point I'm trying to make is that you really don't know for sure exactly what's going on under the covers. All the guesses and hypothesis you can muster don't amount to hardly anything concrete for really making such decisions.

Does that mean you can't really do any useful testing? **Definitely not!**

What this boils down to is that testing *not real* code gives you *not real* results. In so much as is possible and practical, you should test actual real, non-trivial snippets of your code, and under as best of real conditions as you can actually hope to. Only then will the results you get have a chance to approximate reality.

Microbenchmarks like `++x` vs `x++` are so incredibly likely to be bogus, we might as well just flatly assume them as such.

## jsPerf.com

While Benchmark.js is useful for testing the performance of your code in whatever JS environment you're running, it cannot be stressed enough that you need to compile test results from lots of different environments (desktop browsers, mobile devices, etc.) if you want to have any hope of reliable test conclusions.

For example, Chrome on a high-end desktop machine is not likely to perform anywhere near the same as Chrome mobile on a smartphone. And a smartphone with a full battery charge is not likely to perform anywhere near the same as a smartphone with 2% battery life left, when the device is starting to power down the radio and processor.

If you want to make assertions like "X is faster than Y" in any reasonable sense across more than just a single environment, you're going to need to actually test as many of those real world environments as possible. Just because Chrome executes some X operation faster than Y doesn't mean that all browsers do. And of course you also probably will want to cross-reference the results of multiple browser test runs with the demographics of your users.

There's an awesome website for this purpose called jsPerf (http://jsperf.com). It uses the Benchmark.js library we talked about earlier to run statistically accurate and reliable tests, and makes the test on an openly available URL that you can pass around to others.

Each time a test is run, the results are collected and persisted with the test, and the cumulative test results are graphed on the page for anyone to see.

When creating a test on the site, you start out with two test cases to fill in, but you can add as many as you need. You also have the ability to set up `setup` code that is run at the beginning of each test cycle and `teardown` code run at the end of each cycle.

**Note:** A trick for doing just one test case (if you're benchmarking a single approach instead of a head-to-head) is to fill in the second test input boxes with placeholder text on first creation, then edit the test and leave the second test blank, which will delete it. You can always add more test cases later.

You can define the initial page setup (importing libraries, defining utility helper functions, declaring variables, etc.). There are also options for defining setup and teardown behavior if needed -- consult the "Setup/Teardown" section in the Benchmark.js discussion earlier.

### Sanity Check

jsPerf is a fantastic resource, but there's an awful lot of tests published that when you analyze them are quite flawed or bogus, for any of a variety of reasons as outlined so far in this chapter.

Consider:

```js
// Case 1
var x = [];
for (var i=0; i<10; i++) {
	x[i] = "x";
}

// Case 2
var x = [];
for (var i=0; i<10; i++) {
	x[x.length] = "x";
}

// Case 3
var x = [];
for (var i=0; i<10; i++) {
	x.push( "x" );
}
```

Some observations to ponder about this test scenario:

* It's extremely common for devs to put their own loops into test cases, and they forget that Benchmark.js already does all the repetition you need. There's a really strong chance that the `for` loops in these cases are totally unnecessary noise.
* The declaring and initializing of `x` is included in each test case, possibly unnecessarily. Recall from earlier that if `x = []` were in the `setup` code, it wouldn't actually be run before each test iteration, but instead once at the beginning of each cycle. That means `x` would continue growing quite large, not just the size `10` implied by the `for` loops.

   So is the intent to make sure the tests are constrained only to how the JS engine behaves with very small arrays (size `10`)? That *could* be the intent, but if it is, you have to consider if that's not focusing far too much on nuanced internal implementation details.

   On the other hand, does the intent of the test embrace the context that the arrays will actually be growing quite large? Is the JS engines' behavior with larger arrays relevant and accurate when compared with the intended real world usage?

* Is the intent to find out how much `x.length` or `x.push(..)` add to the performance of the operation to append to the `x` array? OK, that might be a valid thing to test. But then again, `push(..)` is a function call, so of course it's going to be slower than `[..]` access. Arguably, cases 1 and 2 are fairer than case 3.

Here's another example that illustrates a common apples-to-oranges flaw:

```js
// Case 1
var x = ["John","Albert","Sue","Frank","Bob"];
x.sort();

// Case 2
var x = ["John","Albert","Sue","Frank","Bob"];
x.sort( function mySort(a,b){
	if (a < b) return -1;
	if (a > b) return 1;
	return 0;
} );
```

Here, the obvious intent is to find out how much slower the custom `mySort(..)` comparator is than the built-in default comparator. But by specifying the function `mySort(..)` as inline function expression, you've created an unfair/bogus test. Here, the second case is not only testing a custom user JS function, **but it's also testing creating a new function expression for each iteration.**

Would it surprise you to find out that if you run a similar test but update it to isolate only for creating an inline function expression versus using a pre-declared function, the inline function expression creation can be from 2% to 20% slower!?

Unless your intent with this test *is* to consider the inline function expression creation "cost," a better/fairer test would put `mySort(..)`'s declaration in the page setup -- don't put it in the test `setup` as that's unnecessary redeclaration for each cycle -- and simply reference it by name in the test case: `x.sort(mySort)`.

Building on the previous example, another pitfall is in opaquely avoiding or adding "extra work" to one test case that creates an apples-to-oranges scenario:

```js
// Case 1
var x = [12,-14,0,3,18,0,2.9];
x.sort();

// Case 2
var x = [12,-14,0,3,18,0,2.9];
x.sort( function mySort(a,b){
	return a - b;
} );
```

Setting aside the previously mentioned inline function expression pitfall, the second case's `mySort(..)` works in this case because you have provided it numbers, but would have of course failed with strings. The first case doesn't throw an error, but it actually behaves differently and has a different outcome! It should be obvious, but: **a different outcome between two test cases almost certainly invalidates the entire test!**

But beyond the different outcomes, in this case, the built in `sort(..)`'s comparator is actually doing "extra work" that `mySort()` does not, in that the built-in one coerces the compared values to strings and does lexicographic comparison. The first snippet results in `[-14, 0, 0, 12, 18, 2.9, 3]` while the second snippet results (likely more accurately based on intent) in `[-14, 0, 0, 2.9, 3, 12, 18]`.

So that test is unfair because it's not actually doing the same task between the cases. Any results you get are bogus.

These same pitfalls can even be much more subtle:

```js
// Case 1
var x = false;
var y = x ? 1 : 2;

// Case 2
var x;
var y = x ? 1 : 2;
```

Here, the intent might be to test the performance impact of the coercion to a Boolean that the `? :` operator will do if the `x` expression is not already a Boolean (see the *Types & Grammar* title of this book series). So, you're apparently OK with the fact that there is extra work to do the coercion in the second case.

The subtle problem? You're setting `x`'s value in the first case and not setting it in the other, so you're actually doing work in the first case that you're not doing in the second. To eliminate any potential (albeit minor) skew, try:

```js
// Case 1
var x = false;
var y = x ? 1 : 2;

// Case 2
var x = undefined;
var y = x ? 1 : 2;
```

Now there's an assignment in both cases, so the thing you want to test -- the coercion of `x` or not -- has likely been more accurately isolated and tested.

## Writing Good Tests

Let me see if I can articulate the bigger point I'm trying to make here.

Good test authoring requires careful analytical thinking about what differences exist between two test cases and whether the differences between them are *intentional* or *unintentional*.

Intentional differences are of course normal and OK, but it's too easy to create unintentional differences that skew your results. You have to be really, really careful to avoid that skew. Moreover, you may intend a difference but it may not be obvious to other readers of your test what your intent was, so they may doubt (or trust!) your test incorrectly. How do you fix that?

**Write better, clearer tests.** But also, take the time to document (using the jsPerf.com "Description" field and/or code comments) exactly what the intent of your test is, even to the nuanced detail. Call out the intentional differences, which will help others and your future self to better identify unintentional differences that could be skewing the test results.

Isolate things which aren't relevant to your test by pre-declaring them in the page or test setup settings so they're outside the timed parts of the test.

Instead of trying to narrow in on a tiny snippet of your real code and benchmarking just that piece out of context, tests and benchmarks are better when they include a larger (while still relevant) context. Those tests also tend to run slower, which means any differences you spot are more relevant in context.

## Microperformance

OK, until now we've been dancing around various microperformance issues and generally looking disfavorably upon obsessing about them. I want to take just a moment to address them directly.

The first thing you need to get more comfortable with when thinking about performance benchmarking your code is that the code you write is not always the code the engine actually runs. We briefly looked at that topic back in Chapter 1 when we discussed statement reordering by the compiler, but here we're going to suggest the compiler can sometimes decide to run different code than you wrote, not just in different orders but different in substance.

Let's consider this piece of code:

```js
var foo = 41;

(function(){
	(function(){
		(function(baz){
			var bar = foo + baz;
			// ..
		})(1);
	})();
})();
```

You may think about the `foo` reference in the innermost function as needing to do a three-level scope lookup. We covered in the *Scope & Closures* title of this book series how lexical scope works, and the fact that the compiler generally caches such lookups so that referencing `foo` from different scopes doesn't really practically "cost" anything extra.

But there's something deeper to consider. What if the compiler realizes that `foo` isn't referenced anywhere else but that one location, and it further notices that the value never is anything except the `41` as shown?

Isn't it quite possible and acceptable that the JS compiler could decide to just remove the `foo` variable entirely, and *inline* the value, such as this:

```js
(function(){
	(function(){
		(function(baz){
			var bar = 41 + baz;
			// ..
		})(1);
	})();
})();
```

**Note:** Of course, the compiler could probably also do a similar analysis and rewrite with the `baz` variable here, too.

When you begin to think about your JS code as being a hint or suggestion to the engine of what to do, rather than a literal requirement, you realize that a lot of the obsession over discrete syntactic minutia is most likely unfounded.

Another example:

```js
function factorial(n) {
	if (n < 2) return 1;
	return n * factorial( n - 1 );
}

factorial( 5 );		// 120
```

Ah, the good ol' fashioned "factorial" algorithm! You might assume that the JS engine will run that code mostly as is. And to be honest, it might -- I'm not really sure.

But as an anecdote, the same code expressed in C and compiled with advanced optimizations would result in the compiler realizing that the call `factorial(5)` can just be replaced with the constant value `120`, eliminating the function and call entirely!

Moreover, some engines have a practice called "unrolling recursion," where it can realize that the recursion you've expressed can actually be done "easier" (i.e., more optimally) with a loop. It's possible the preceding code could be *rewritten* by a JS engine to run as:

```js
function factorial(n) {
	if (n < 2) return 1;

	var res = 1;
	for (var i=n; i>1; i--) {
		res *= i;
	}
	return res;
}

factorial( 5 );		// 120
```

Now, let's imagine that in the earlier snippet you had been worried about whether `n * factorial(n-1)` or `n *= factorial(--n)` runs faster. Maybe you even did a performance benchmark to try to figure out which was better. But you miss the fact that in the bigger context, the engine may not run either line of code because it may unroll the recursion!

Speaking of `--`, `--n` versus `n--` is often cited as one of those places where you can optimize by choosing the `--n` version, because theoretically it requires less effort down at the assembly level of processing.

That sort of obsession is basically nonsense in modern JavaScript. That's the kind of thing you should be letting the engine take care of. You should write the code that makes the most sense. Compare these three `for` loops:

```js
// Option 1
for (var i=0; i<10; i++) {
	console.log( i );
}

// Option 2
for (var i=0; i<10; ++i) {
	console.log( i );
}

// Option 3
for (var i=-1; ++i<10; ) {
	console.log( i );
}
```

Even if you have some theory where the second or third option is more performant than the first option by a tiny bit, which is dubious at best, the third loop is more confusing because you have to start with `-1` for `i` to account for the fact that `++i` pre-increment is used. And the difference between the first and second options is really quite irrelevant.

It's entirely possible that a JS engine may see a place where `i++` is used and realize that it can safely replace it with the `++i` equivalent, which means your time spent deciding which one to pick was completely wasted and the outcome moot.

Here's another common example of silly microperformance obsession:

```js
var x = [ .. ];

// Option 1
for (var i=0; i < x.length; i++) {
	// ..
}

// Option 2
for (var i=0, len = x.length; i < len; i++) {
	// ..
}
```

The theory here goes that you should cache the length of the `x` array in the variable `len`, because ostensibly it doesn't change, to avoid paying the price of `x.length` being consulted for each iteration of the loop.

If you run performance benchmarks around `x.length` usage compared to caching it in a `len` variable, you'll find that while the theory sounds nice, in practice any measured differences are statistically completely irrelevant.

In fact, in some engines like v8, it can be shown (http://mrale.ph/blog/2014/12/24/array-length-caching.html) that you could make things slightly worse by pre-caching the length instead of letting the engine figure it out for you. Don't try to outsmart your JavaScript engine, you'll probably lose when it comes to performance optimizations.

### Not All Engines Are Alike

The different JS engines in various browsers can all be "spec compliant" while having radically different ways of handling code. The JS specification doesn't require anything performance related -- well, except ES6's "Tail Call Optimization" covered later in this chapter.

The engines are free to decide that one operation will receive its attention to optimize, perhaps trading off for lesser performance on another operation. It can be very tenuous to find an approach for an operation that always runs faster in all browsers.

There's a movement among some in the JS dev community, especially those who work with Node.js, to analyze the specific internal implementation details of the v8 JavaScript engine and make decisions about writing JS code that is tailored to take best advantage of how v8 works. You can actually achieve a surprisingly high degree of performance optimization with such endeavors, so the payoff for the effort can be quite high.

Some commonly cited examples (https://github.com/petkaantonov/bluebird/wiki/Optimization-killers) for v8:

* Don't pass the `arguments` variable from one function to any other function, as such "leakage" slows down the function implementation.
* Isolate a `try..catch` in its own function. Browsers struggle with optimizing any function with a `try..catch` in it, so moving that construct to its own function means you contain the de-optimization harm while letting the surrounding code be optimizable.

But rather than focus on those tips specifically, let's sanity check the v8-only optimization approach in a general sense.

Are you genuinely writing code that only needs to run in one JS engine? Even if your code is entirely intended for Node.js *right now*, is the assumption that v8 will *always* be the used JS engine reliable? Is it possible that someday a few years from now, there's another server-side JS platform besides Node.js that you choose to run your code on? What if what you optimized for before is now a much slower way of doing that operation on the new engine?

Or what if your code always stays running on v8 from here on out, but v8 decides at some point to change the way some set of operations works such that what used to be fast is now slow, and vice versa?

These scenarios aren't just theoretical, either. It used to be that it was faster to put multiple string values into an array and then call `join("")` on the array to concatenate the values than to just use `+` concatenation directly with the values. The historical reason for this is nuanced, but it has to do with internal implementation details about how string values were stored and managed in memory.

As a result, "best practice" advice at the time disseminated across the industry suggesting developers always use the array `join(..)` approach. And many followed.

Except, somewhere along the way, the JS engines changed approaches for internally managing strings, and specifically put in optimizations for `+` concatenation. They didn't slow down `join(..)` per se, but they put more effort into helping `+` usage, as it was still quite a bit more widespread.

**Note:** The practice of standardizing or optimizing some particular approach based mostly on its existing widespread usage is often called (metaphorically) "paving the cowpath."

Once that new approach to handling strings and concatenation took hold, unfortunately all the code out in the wild that was using array `join(..)` to concatenate strings was then sub-optimal.

Another example: at one time, the Opera browser differed from other browsers in how it handled the boxing/unboxing of primitive wrapper objects (see the *Types & Grammar* title of this book series). As such, their advice to developers was to use a `String` object instead of the primitive `string` value if properties like `length` or methods like `charAt(..)` needed to be accessed. This advice may have been correct for Opera at the time, but it was literally completely opposite for other major contemporary browsers, as they had optimizations specifically for the `string` primitives and not their object wrapper counterparts.

I think these various gotchas are at least possible, if not likely, for code even today. So I'm very cautious about making wide ranging performance optimizations in my JS code based purely on engine implementation details, **especially if those details are only true of a single engine**.

The reverse is also something to be wary of: you shouldn't necessarily change a piece of code to work around one engine's difficulty with running a piece of code in an acceptably performant way.

Historically, IE has been the brunt of many such frustrations, given that there have been plenty of scenarios in older IE versions where it struggled with some performance aspect that other major browsers of the time seemed not to have much trouble with. The string concatenation discussion we just had was actually a real concern back in the IE6 and IE7 days, where it was possible to get better performance out of `join(..)` than `+`.

But it's troublesome to suggest that just one browser's trouble with performance is justification for using a code approach that quite possibly could be sub-optimial in all other browsers. Even if the browser in question has a large market share for your site's audience, it may be more practical to write the proper code and rely on the browser to update itself with better optimizations eventually.

"There is nothing more permanent than a temporary hack." Chances are, the code you write now to work around some performance bug will probably outlive the performance bug in the browser itself.

In the days when a browser only updated once every five years, that was a tougher call to make. But as it stands now, browsers across the board are updating at a much more rapid interval (though obviously the mobile world still lags), and they're all competing to optimize web features better and better.

If you run across a case where a browser *does* have a performance wart that others don't suffer from, make sure to report it to them through whatever means you have available. Most browsers have open public bug trackers suitable for this purpose.

**Tip:** I'd only suggest working around a performance issue in a browser if it was a really drastic show-stopper, not just an annoyance or frustration. And I'd be very careful to check that the performance hack didn't have noticeable negative side effects in another browser.

### Big Picture

Instead of worrying about all these microperformance nuances, we should instead be looking at big-picture types of optimizations.

How do you know what's big picture or not? You have to first understand if your code is running on a critical path or not. If it's not on the critical path, chances are your optimizations are not worth much.

Ever heard the admonition, "that's premature optimization!"? It comes from a famous quote from Donald Knuth: "premature optimization is the root of all evil.". Many developers cite this quote to suggest that most optimizations are "premature" and are thus a waste of effort. The truth is, as usual, more nuanced.

Here is Knuth's quote, in context:

> Programmers waste enormous amounts of time thinking about, or worrying about, the speed of **noncritical** parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that **critical** 3%. [emphasis added]

(http://web.archive.org/web/20130731202547/http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf, Computing Surveys, Vol 6, No 4, December 1974)

I believe it's a fair paraphrasing to say that Knuth *meant*: "non-critical path optimization is the root of all evil." So the key is to figure out if your code is on the critical path -- you should optimize it! -- or not.

I'd even go so far as to say this: no amount of time spent optimizing critical paths is wasted, no matter how little is saved; but no amount of optimization on noncritical paths is justified, no matter how much is saved.

If your code is on the critical path, such as a "hot" piece of code that's going to be run over and over again, or in UX critical places where users will notice, like an animation loop or CSS style updates, then you should spare no effort in trying to employ relevant, measurably significant optimizations.

For example, consider a critical path animation loop that needs to coerce a string value to a number. There are of course multiple ways to do that (see the *Types & Grammar* title of this book series), but which one if any is the fastest?

```js
var x = "42";	// need number `42`

// Option 1: let implicit coercion automatically happen
var y = x / 2;

// Option 2: use `parseInt(..)`
var y = parseInt( x, 0 ) / 2;

// Option 3: use `Number(..)`
var y = Number( x ) / 2;

// Option 4: use `+` unary operator
var y = +x / 2;

// Option 5: use `|` unary operator
var y = (x | 0) / 2;
```

**Note:** I will leave it as an exercise to the reader to set up a test if you're interested in examining the minute differences in performance among these options.

When considering these different options, as they say, "One of these things is not like the others." `parseInt(..)` does the job, but it also does a lot more -- it parses the string rather than just coercing. You can probably guess, correctly, that `parseInt(..)` is a slower option, and you should probably avoid it.

Of course, if `x` can ever be a value that **needs parsing**, such as `"42px"` (like from a CSS style lookup), then `parseInt(..)` really is the only suitable option!

`Number(..)` is also a function call. From a behavioral perspective, it's identical to the `+` unary operator option, but it may in fact be a little slower, requiring more machinery to execute the function. Of course, it's also possible that the JS engine recognizes this behavioral symmetry and just handles the inlining of `Number(..)`'s behavior (aka `+x`) for you!

But remember, obsessing about `+x` versus `x | 0` is in most cases likely a waste of effort. This is a microperformance issue, and one that you shouldn't let dictate/degrade the readability of your program.

While performance is very important in critical paths of your program, it's not the only factor. Among several options that are roughly similar in performance, readability should be another important concern.

## Tail Call Optimization (TCO)

As we briefly mentioned earlier, ES6 includes a specific requirement that ventures into the world of performance. It's related to a specific form of optimization that can occur with function calls: *tail call optimization*.

Briefly, a "tail call" is a function call that appears at the "tail" of another function, such that after the call finishes, there's nothing left to do (except perhaps return its result value).

For example, here's a non-recursive setup with tail calls:

```js
function foo(x) {
	return x;
}

function bar(y) {
	return foo( y + 1 );	// tail call
}

function baz() {
	return 1 + bar( 40 );	// not tail call
}

baz();						// 42
```

`foo(y+1)` is a tail call in `bar(..)` because after `foo(..)` finishes, `bar(..)` is also finished except in this case returning the result of the `foo(..)` call. However, `bar(40)` is *not* a tail call because after it completes, its result value must be added to `1` before `baz()` can return it.

Without getting into too much nitty-gritty detail, calling a new function requires an extra amount of reserved memory to manage the call stack, called a "stack frame." So the preceding snippet would generally require a stack frame for each of `baz()`, `bar(..)`, and `foo(..)` all at the same time.

However, if a TCO-capable engine can realize that the `foo(y+1)` call is in *tail position* meaning `bar(..)` is basically complete, then when calling `foo(..)`, it doesn't need to create a new stack frame, but can instead reuse the existing stack frame from `bar(..)`. That's not only faster, but it also uses less memory.

That sort of optimization isn't a big deal in a simple snippet, but it becomes a *much bigger deal* when dealing with recursion, especially if the recursion could have resulted in hundreds or thousands of stack frames. With TCO the engine can perform all those calls with a single stack frame!

Recursion is a hairy topic in JS because without TCO, engines have had to implement arbitrary (and different!) limits to how deep they will let the recursion stack get before they stop it, to prevent running out of memory. With TCO, recursive functions with *tail position* calls can essentially run unbounded, because there's never any extra usage of memory!

Consider that recursive `factorial(..)` from before, but rewritten to make it TCO friendly:

```js
function factorial(n) {
	function fact(n,res) {
		if (n < 2) return res;

		return fact( n - 1, n * res );
	}

	return fact( n, 1 );
}

factorial( 5 );		// 120
```

This version of `factorial(..)` is still recursive, but it's also optimizable with TCO, because both inner `fact(..)` calls are in *tail position*.

**Note:** It's important to note that TCO only applies if there's actually a tail call. If you write recursive functions without tail calls, the performance will still fall back to normal stack frame allocation, and the engines' limits on such recursive call stacks will still apply. Many recursive functions can be rewritten as we just showed with `factorial(..)`, but it takes careful attention to detail.

One reason that ES6 requires engines to implement TCO rather than leaving it up to their discretion is because the *lack of TCO* actually tends to reduce the chances that certain algorithms will be implemented in JS using recursion, for fear of the call stack limits.

If the lack of TCO in the engine would just gracefully degrade to slower performance in all cases, it wouldn't probably have been something that ES6 needed to *require*. But because the lack of TCO can actually make certain programs impractical, it's more an important feature of the language than just a hidden implementation detail.

ES6 guarantees that from now on, JS developers will be able to rely on this optimization across all ES6+ compliant browsers. That's a win for JS performance!

## Review

Effectively benchmarking performance of a piece of code, especially to compare it to another option for that same code to see which approach is faster, requires careful attention to detail.

Rather than rolling your own statistically valid benchmarking logic, just use the Benchmark.js library, which does that for you. But be careful about how you author tests, because it's far too easy to construct a test that seems valid but that's actually flawed -- even tiny differences can skew the results to be completely unreliable.

It's important to get as many test results from as many different environments as possible to eliminate hardware/device bias. jsPerf.com is a fantastic website for crowdsourcing performance benchmark test runs.

Many common performance tests unfortunately obsess about irrelevant microperformance details like `x++` versus `++x`. Writing good tests means understanding how to focus on big picture concerns, like optimizing on the critical path, and avoiding falling into traps like different JS engines' implementation details.

Tail call optimization (TCO) is a required optimization as of ES6 that will make some recursive patterns practical in JS where they would have been impossible otherwise. TCO allows a function call in the *tail position* of another function to execute without needing any extra resources, which means the engine no longer needs to place arbitrary restrictions on call stack depth for recursive algorithms.


text:
interface SAM {
    String foo(int n);
}

class JTest {
    static void samTest(SAM sam) { }
}

redpajama_set_name: RedPajamaGithub


text:
'''

New Integration Test for creating KVM VM and quickly destroy it without checking.

@author: Youyk
'''

import zstackwoodpecker.test_util as test_util
import zstackwoodpecker.test_state as test_state
import zstackwoodpecker.test_lib as test_lib
import zstackwoodpecker.operations.resource_operations as res_ops
import zstackwoodpecker.zstack_test.zstack_test_vm as test_vm_header
import time
import os

vm = None

def test():
    global vm
    vm_creation_option = test_util.VmOption()
    image_name = os.environ.get('imageName_s')
    image_uuid = test_lib.lib_get_image_by_name(image_name).uuid
    #l3_name = os.environ.get('l3NoVlanNetworkName1')
    l3_name = os.environ.get('l3VlanNetworkName1')

    l3_net_uuid = test_lib.lib_get_l3_by_name(l3_name).uuid
    conditions = res_ops.gen_query_conditions('type', '=', 'UserVm')
    instance_offering_uuid = res_ops.query_resource(res_ops.INSTANCE_OFFERING, conditions)[0].uuid
    vm_creation_option.set_l3_uuids([l3_net_uuid])
    vm_creation_option.set_image_uuid(image_uuid)
    vm_creation_option.set_instance_offering_uuid(instance_offering_uuid)
    vm_creation_option.set_name('multihost_basic_vm')
    vm = test_vm_header.ZstackTestVm()
    vm.set_creation_option(vm_creation_option)
    vm.create()
    #time.sleep(5)
    #vm.check()
    #vm.destroy()
    test_util.test_pass('Create VM Test Success')

#Will be called only if exception happens in test().
def error_cleanup():
    global vm
    if vm:
        try:
            vm.destroy()
        except:
            pass


text:
<?php

/**
 * Class ClientDash_Functions
 *
 * The main, extensible class for all other classes within Client Dash.
 *
 * @package    WordPress
 * @subpackage ClientDash
 *
 * @category   Base Functionality
 *
 * @since      Client Dash 1.5
 */
abstract class ClientDash_Functions {

	/**
	 * Checks to see if we're on a specific page and tab.
	 *
	 * @since Client Dash 1.6
	 *
	 * @param string $page The page to check.
	 * @param        bool /string $tab If supplied, will also check that the given tab is active.
	 *
	 * @return bool True of on the page (and tab), false otherwise.
	 */
	public static function is_cd_page( $page, $tab = false ) {

		// Check the page
		if ( isset( $_GET['page'] ) && $_GET['page'] == $page ) {

			// If also set a tab, check that
			if ( $tab ) {
				if ( isset( $_GET['tab'] ) && $tab == $tab ) {
					return true;
				} else {
					return false;
				}
			}

			return true;
		}

		return false;
	}

	/**
	 * Outputs the default Client Dash toggle switch (on|off).
	 *
	 * @since Client Dash 1.6
	 *
	 * @param string $name The name of the input.
	 * @param string|int $value The value for the input to output.
	 * @param string|int $current_val The current value of whatever the input has output.
	 * @param bool $horizontal Optional. Whether the switch is vertical or horizontal.
	 * @param bool $echo Optional. Whether to echo the HTML or just return it.
	 * @param bool $invert Optional. Whether to invert the relationship between the value and on|off.
	 * @param bool|array $atts Optional. Additional attributes for the item.
	 *
	 * @return string HTML of toggle switch.
	 */
	public static function toggle_switch( $name, $value, $current_val, $horizontal = false, $echo = true, $invert = false, $atts = false ) {

		// Setup orientation
		if ( $horizontal ) {
			$horizontal = 'horizontal';
		}

		// If the current value matches the input value, it's not disabled
		// (if $invert is true, reverse the output)
		$disabled = $invert ? false : true;
		if ( $value == $current_val ) {
			$disabled = $invert ? true : false;
		}

		// The HTML output
		$html = ' $att_val ) {
				$html .= " $att='$att_val' ";
			}
		}
		$html .= '>';
		$html .= "<input type='hidden' id='$name' name='$name' value='$value' " . ( $disabled && ! $invert || $invert && ! $disabled ? 'disabled' : '' ) . '/>';
		$html .= '';

		// Echo by default, return if told so
		if ( $echo ) {
			echo $html;
		} else {
			return $html;
		}
	}

	/**
	 * Outputs a helpful tip that can be closed.
	 *
	 * @since Client Dash 1.5
	 *
	 * @param string $content The content of the tip.
	 * @param string $position The position of the tip. (left or right)
	 * @param string $classes A string containing all the classes to add to the tip.
	 *
	 * @return string The tip.
	 */
	public static function pointer( $content, $position = 'left', $classes = null ) {

		return "$contentX";
	}

	/**
	 * Outputs the page title with Client Dash standards.
	 *
	 * @since Client Dash 1.2
	 *
	 * @param string $page The page we're on. Default 'account'.
	 */
	public static function the_page_title( $page = 'account' ) {

		global $ClientDash;

		// Get the current dashicon
		$dashicon = get_option( 'cd_dashicon_' . $page, $ClientDash->option_defaults[ 'dashicon_' . $page ] );

		// If Webmaster, get name
		if ( $page == 'webmaster' ) {
			$page = get_option( 'cd_webmaster_name', $ClientDash->option_defaults['webmaster_name'] );
		}

		echo '
' . ucwords( $page ) . '
';
	}

	/**
	 * The main function for building the CD pages.
	 *
	 * @since Client Dash 1.0
	 */
	public static function create_tab_page() {

		global $ClientDash;

		// Get the page for building url
		$current_page = str_replace( 'cd_', '', $_GET['page'] );

		// If a tab is open, get it
		if ( isset( $_GET['tab'] ) ) {
			$active_tab = $_GET['tab'];
		} else {
			$active_tab = null;
		}

		// If a section is open, get it
		if ( isset( $_GET['section'] ) ) {
			$active_section = $_GET['section'];
		} else {
			$active_section = null;
		}

		// If no content on this page, show error and bail
		if ( empty( $ClientDash->content_sections[ $current_page ] ) ) {
			self::error_nag( __( 'This page has no content', 'client-dash' ) );

			return;
		}
		// Cycle through all tabs and output the menu
		echo '
';
		$i = 0;
		foreach ( $ClientDash->content_sections[ $current_page ] as $tab_ID => $props ) {
			$i ++;

			// If active tab, set class
			if ( $active_tab == $tab_ID || ! $active_tab && $i == 1 ) {
				$active = 'nav-tab-active';
			} else {
				$active = '';
			}

			// Output the tab menu item
			echo '' . $props['name'] . '';
		}
		echo '
';

		// If no active tab was set, take the first one
		if ( ! $active_tab ) {
			reset( $ClientDash->content_sections[ $current_page ] );
			$active_tab = key( $ClientDash->content_sections[ $current_page ] );
		}

		// Cycle through all sections and output the menu
		// Skip if total is only 1
		$total = count( $ClientDash->content_sections[ $current_page ][ $active_tab ]['content-sections'] );
		if ( $total > 1 ) {
			echo '
';

			$i = 0;
			foreach ( $ClientDash->content_sections[ $current_page ][ $active_tab ]['content-sections'] as $section_ID => $props ) {
				$i ++;

				echo '
';

				// If active section, set class
				if ( $active_section == $section_ID || ! $active_section && $i == 1 ) {
					$active = 'current';
				} else {
					$active = '';
				}

				// Add on a pipe if not the last item
				$output_text = $props['name'] . ( $i < $total ? ' |' : '' );

				// Output the section menu item
				echo "$output_text";

				echo '
';
			}
			echo '
';
		}

		// If no active section was set, take the first one
		if ( ! $active_section ) {
			reset( $ClientDash->content_sections[ $current_page ][ $active_tab ]['content-sections'] );
			$active_section = key( $ClientDash->content_sections[ $current_page ][ $active_tab ]['content-sections'] );
		}

		// Get our current section
		$section_output = $ClientDash->content_sections[ $current_page ][ $active_tab ]['content-sections'][ $active_section ];

		// This calls the dynamic class and dynamic callback function
		echo '
';

		// Only call the tab if it exists
		if ( is_callable( $section_output['callback'] ) ) {
			call_user_func( $section_output['callback'] );
		} else {

			// Let the user know the tab doesn't exist
			self::error_nag( __( 'This tab doesn\'t seem to exist! Sorry about that.', 'client-dash' ) );

			// Also need to remove the submit button if on settings pages
			if ( $_GET['page'] == 'cd_settings' ) {
				add_filter( 'cd_submit', '__return_false' );
			}
		}

		echo '
';
	}

	/**
	 * Creates content sections.
	 *
	 * This function creates a content section for Client Dash. It can be set to
	 * go into a specific tab in a specific tab.
	 *
	 * @since Client Dash 1.4
	 *
	 * @param array $content_section All of the arguments for the function.
	 */
	public static function add_content_section( $content_section ) {

		global $ClientDash;

		/**
		 * Filter each content section that is added.
		 *
		 * @since Client Dash 1.6
		 */
		$content_section = apply_filters( 'cd_add_content_section', $content_section );

		if ( ! isset( $content_section['priority'] ) ) {
			$content_section['priority'] = 10;
		}

		// Generate the content section ID
		$ID = self::translate_name_to_id( $content_section['name'] );

		// Fix up the tab name (to allow spaces and such)
		$tab_ID = self::translate_name_to_id( $content_section['tab'] );

		// Fix up the page name (to allow spaces and such)
		$page = self::translate_name_to_id( $content_section['page'] );

		// Add to the array
		$ClientDash->content_sections[ $page ][ $tab_ID ]['name'] = $content_section['tab'];

		$ClientDash->content_sections[ $page ][ $tab_ID ]['content-sections'][ $ID ] = array(
			'name'     => $content_section['name'],
			'callback' => $content_section['callback'],
			'priority' => $content_section['priority']
		);

		// Also add for the unmodified version
		$ClientDash->content_sections_unmodified[ $page ][ $tab_ID ]['name'] = $content_section['tab'];

		$ClientDash->content_sections_unmodified[ $page ][ $tab_ID ]['content-sections'][ $ID ] = array(
			'name'     => $content_section['name'],
			'callback' => $content_section['callback'],
			'priority' => $content_section['priority']
		);
	}

	/**
	 * Resets all Client Dash settings.
	 *
	 * @since Client Dash 1.5.4
	 *
	 * @param bool $force Whether or not to overrite existing values.
	 */
	public static function reset_settings( $force = false ) {

		global $ClientDash;

		foreach ( $ClientDash->option_defaults as $name => $value ) {
			$existing_option = get_option( "cd_$name" );

			if ( $force ) {
				update_option( "cd_$name", $value );
			} elseif ( empty( $existing_option ) ) {
				update_option( "cd_$name", $value );
			}
		}
	}

	/**
	 * Strips out spaces and dashes and replaces them with underscores. Also
	 * translates to lowercase.
	 *
	 * @since Client Dash 1.3
	 *
	 * @param string $name The name to be translated.
	 *
	 * @return string Translated ID.
	 */
	public static function translate_name_to_id( $name ) {

		return strtolower( str_replace( array( ' ', '-' ), '_', $name ) );
	}

	/**
	 * Replaces underscores with spaces and capitalizes words.
	 *
	 * @since Client Dash 1.6
	 *
	 * @param string $ID The ID to be translated.
	 *
	 * @return string Translated name.
	 */
	public static function translate_id_to_name( $ID ) {

		return ucwords( str_replace( '_', ' ', $ID ) );
	}

	/**
	 * Gets the current color scheme.
	 *
	 * @since Client Dash 1.2
	 *
	 * @param $which_color
	 *
	 * @return array|bool Current color scheme
	 */
	public static function get_color_scheme( $which_color = null ) {

		global $ClientDash;

		$current_color = get_user_option( 'admin_color' );

		if ( ! isset( $ClientDash->admin_colors[ $current_color ])) {
			return false;
		}

		$colors        = $ClientDash->admin_colors[ $current_color ];

		$output = array(
			'primary'      => $colors->colors[1],
			'primary-dark' => $colors->colors[0],
			'secondary'    => $colors->colors[2],
			'tertiary'     => $colors->colors[3]
		);

		if ( isset( $output[ $which_color ] ) ) {
			return $output[ $which_color ];
		} else {
			return $output;
		}
	}

	/**
	 * Gets the size of a directory on the server.
	 *
	 * @since ClientDash 1.1
	 *
	 * @param $path
	 *
	 * @return mixed
	 */
	public static function get_dir_size( $path ) {

		$totalsize  = 0;
		$totalcount = 0;
		$dircount   = 0;
		if ( $handle = opendir( $path ) ) {
			while ( false !== ( $file = readdir( $handle ) ) ) {
				$nextpath = $path . '/' . $file;
				if ( $file != '.' && $file != '..' && ! is_link( $nextpath ) ) {
					if ( is_dir( $nextpath ) ) {
						$dircount ++;
						$result = self::get_dir_size( $nextpath );
						$totalsize += $result['size'];
						$totalcount += $result['count'];
						$dircount += $result['dircount'];
					} elseif ( is_file( $nextpath ) ) {
						$totalsize += filesize( $nextpath );
						$totalcount ++;
					}
				}
			}
		}
		closedir( $handle );
		$total['size']     = $totalsize;
		$total['count']    = $totalcount;
		$total['dircount'] = $dircount;

		return $total;
	}

	/**
	 * Correctly formats the bytes size into a more readable size.
	 *
	 * @since Client Dash 1.1
	 *
	 * @param int $size Size in bytes
	 *
	 * @return string
	 */
	public static function format_dir_size( $size ) {

		if ( $size < 1024 ) {
			return $size . " bytes";
		} else if ( $size < ( 1024 * 1024 ) ) {
			$size = round( $size / 1024, 1 );

			return $size . " KB";
		} else if ( $size < ( 1024 * 1024 * 1024 ) ) {
			$size = round( $size / ( 1024 * 1024 ), 1 );

			return $size . " MB";
		} else {
			$size = round( $size / ( 1024 * 1024 * 1024 ), 1 );

			return $size . " GB";
		}
	}

	/**
	 * This allows us to use array_key_exists recursively.
	 *
	 * @since Client Dash 1.5
	 *
	 * @param string $needle The array key to search for.
	 * @param array $haystack The array to search in.
	 *
	 * @return bool The result.
	 */
	public static function array_key_exists_r( $needle, $haystack ) {

		$result = array_key_exists( $needle, $haystack );
		if ( $result ) {
			return $result;
		}
		foreach ( $haystack as $v ) {
			if ( is_array( $v ) ) {
				$result = self::array_key_exists_r( $needle, $v );
			}
			if ( $result ) {
				return $result;
			}
		}

		return $result;
	}

	/**
	 * Get's the current user's role.
	 *
	 * @since Client Dash 1.4
	 *
	 * @return mixed The role.
	 */
	public static function get_user_role() {

		global $current_user;
		$user_roles = $current_user->roles;
		$user_role  = array_shift( $user_roles );

		return $user_role;
	}

	/**
	 * Displays a WordPress error nag.
	 *
	 * The nag will only show if the current user has the capabilities that
	 * are defined by the second parameter. This defaults to allowing
	 * everybody to see the message.
	 *
	 * @since Client Dash 1.4
	 *
	 * @param string $message The message to show.
	 * @param string $caps Optional. A WordPress recognized capability.
	 * @param bool $echo Optional. Whether to echo or return the error.
	 *
	 * @return string The error.
	 * is 'read'.
	 */
	public static function error_nag( $message, $caps = 'read', $echo = true ) {

		if ( current_user_can( $caps ) ) {
			if ( $echo ) {
				echo "

$message

";
			} else {
				return "

$message

";
			}
		}
	}

	/**
	 * Displays a WordPress update nag.
	 *
	 * The nag will only show if the current user has the capabilities that
	 * are defined by the second parameter. This defaults to allowing
	 * everybody to see the message.
	 *
	 * @since Client Dash 1.4
	 *
	 * @param string $message The message to show.
	 * @param string $caps . Optional. A WordPress recognized capability. Default
	 *                        is 'read'.
	 */
	public static function update_nag( $message, $caps = 'read' ) {

		if ( current_user_can( $caps ) ) {
			echo "

$message

";
		}
	}

	/**
	 * Returns the settings url.
	 *
	 * @since Client Dash 1.2
	 *
	 * @param string $tab The tab to link to.
	 * @param string $section The content section to link to.
	 *
	 * @return string
	 */
	public static function get_settings_url( $tab = null, $section = null ) {

		return get_admin_url() . 'options-general.php?page=cd_settings' . ( $tab ? "&tab=$tab" : '' ) . ( $section ? "&section=$section" : '' );
	}

	/**
	 * Returns the account url.
	 *
	 * @since Client Dash 1.2
	 *
	 * @param string $tab The tab to link to.
	 * @param string $section The content section to link to.
	 *
	 * @return string
	 */
	public static function get_account_url( $tab = null, $section = null ) {

		return get_admin_url() . 'index.php?page=cd_account' . ( $tab ? "&tab=$tab" : '' ) . ( $section ? "&section=$section" : '' );
	}

	/**
	 * Returns the help url.
	 *
	 * @since Client Dash 1.2
	 *
	 * @param string $tab The tab to link to.
	 * @param string $section The content section to link to.
	 *
	 * @return string
	 */
	public static function get_help_url( $tab = null, $section = null ) {

		return get_admin_url() . 'index.php?page=cd_help' . ( $tab ? "&tab=$tab" : '' ) . ( $section ? "&section=$section" : '' );
	}

	/**
	 * Returns the reports url.
	 *
	 * @since Client Dash 1.2
	 *
	 * @param string $tab The tab to link to.
	 * @param string $section The content section to link to.
	 *
	 * @return string
	 */
	public static function get_reports_url( $tab = null, $section = null ) {

		return get_admin_url() . 'index.php?page=cd_reports' . ( $tab ? "&tab=$tab" : '' ) . ( $section ? "&section=$section" : '' );
	}

	/**
	 * Returns the webmaster url.
	 *
	 * @since Client Dash 1.2
	 *
	 * @param string $tab The tab to link to.
	 * @param string $section The content section to link to.
	 *
	 * @return string
	 */
	public static function get_webmaster_url( $tab = null, $section = null ) {

		return get_admin_url() . 'index.php?page=cd_webmaster' . ( $tab ? "&tab=$tab" : '' ) . ( $section ? "&section=$section" : '' );
	}

	/**
	 * Returns 1.
	 *
	 * Built for use in turning the dashboard columns into one.
	 *
	 * @since Client Dash 1.5
	 */
	public static function return_1() {

		return 1;
	}

	/**
	 * Used in widgets_init.
	 *
	 * @since Client Dash 1.5
	 *
	 * @param mixed $matches Matches from a preg_replace_callback.
	 *
	 * @return string Upped count.
	 */
	public static function replace_count( $matches ) {

		$n = intval( $matches[2] ) + 1;

		return $matches[1] . $n;
	}

	/**
	 * Allows an array of needles instead of just one.
	 *
	 * @since  Client Dash 1.6
	 *
	 * @author Binyamin (stackoverflow)
	 *
	 * @param       $haystack
	 * @param array $needles
	 * @param int $offset
	 *
	 * @return bool|mixed
	 */
	public static function strposa( $haystack, $needles = array(), $offset = 0 ) {
		$chr = array();
		foreach ( $needles as $needle ) {
			$res = strpos( $haystack, $needle, $offset );
			if ( $res !== false ) {
				$chr[ $needle ] = $res;
			}
		}
		if ( empty( $chr ) ) {
			return false;
		}

		return min( $chr );
	}

	/**
	 * Fixes incomplete classes.
	 *
	 * @since 1.6.8
	 *
	 * @param object $object The broken object.
	 *
	 * @return mixed The fixed object.
	 */
	public static function fix_object( &$object ) {

		if ( ! is_object( $object ) && gettype( $object ) == 'object' ) {
			return ( $object = unserialize( serialize( $object ) ) );
		}

		return $object;
	}

	// Widget specific functions
}


text:
package alec_wam.CrystalMod.tiles.machine.worksite.imp;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import alec_wam.CrystalMod.entities.minions.worker.EntityMinionWorker;
import alec_wam.CrystalMod.entities.minions.worker.jobs.JobChopTree;
import alec_wam.CrystalMod.entities.minions.worker.jobs.JobDestoryBlock;
import alec_wam.CrystalMod.entities.minions.worker.jobs.JobPlantCrop;
import alec_wam.CrystalMod.tiles.machine.worksite.InventorySided;
import alec_wam.CrystalMod.tiles.machine.worksite.InventorySided.RelativeSide;
import alec_wam.CrystalMod.tiles.machine.worksite.InventorySided.RotationType;
import alec_wam.CrystalMod.tiles.machine.worksite.ItemSlotFilter;
import alec_wam.CrystalMod.tiles.machine.worksite.TileWorksiteBase;
import alec_wam.CrystalMod.tiles.machine.worksite.TileWorksiteUserBlocks;
import alec_wam.CrystalMod.tiles.machine.worksite.WorkerFilter;
import alec_wam.CrystalMod.tiles.machine.worksite.WorksiteUpgrade;
import alec_wam.CrystalMod.util.BlockUtil;
import alec_wam.CrystalMod.util.HarvestResult;
import alec_wam.CrystalMod.util.ItemStackTools;
import alec_wam.CrystalMod.util.ItemUtil;
import alec_wam.CrystalMod.util.fakeplayer.FakePlayerUtil;
import alec_wam.CrystalMod.util.tool.ChorusPlantUtil;
import alec_wam.CrystalMod.util.tool.ChorusPlantUtil.ChorusPlantData;
import alec_wam.CrystalMod.util.tool.MultiHarvestComparator;
import alec_wam.CrystalMod.util.tool.ToolUtil;
import alec_wam.CrystalMod.util.tool.TreeHarvestUtil;
import alec_wam.CrystalMod.util.tool.TreeUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockChorusFlower;
import net.minecraft.block.BlockDoublePlant;
import net.minecraft.block.BlockFlower;
import net.minecraft.block.BlockSapling;
import net.minecraft.block.BlockTallGrass;
import net.minecraft.block.state.IBlockState;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Enchantments;
import net.minecraft.init.Items;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemDye;
import net.minecraft.item.ItemShears;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.IShearable;
import net.minecraftforge.common.util.Constants;

public class WorksiteTreeFarm extends TileWorksiteUserBlocks {

	/**
	 * flag should be set to true whenever updating inventory internally (e.g.
	 * harvesting blocks) to prevent unnecessary inventory rescanning. should be
	 * set back to false after blocks are added to inventory
	 */
	private boolean shouldCountResources = true;
	int saplingCount;
	int chorusFlowerCount;
	int bonemealCount;
	Set<BlockPos> blocksToChop;
	List<BlockPos> blocksToPlant;
	List<BlockPos> blocksToFertilize;
	List<BlockPos> busyBlocks;
	List<BlockPos> junkBlocks;

	public WorksiteTreeFarm() {
		blocksToChop = new HashSet<BlockPos>();
		blocksToPlant = new ArrayList<BlockPos>();
		blocksToFertilize = new ArrayList<BlockPos>();
		busyBlocks = new ArrayList<BlockPos>();
		junkBlocks = new ArrayList<BlockPos>();

		this.inventory = new InventorySided(this, RotationType.FOUR_WAY, 33) {
			@Override
			public void markDirty() {
				super.markDirty();
				shouldCountResources = true;
			}
		};
		int[] topIndices = ItemUtil.getIndiceArrayForSpread(0, 27);
		int[] frontIndices = ItemUtil.getIndiceArrayForSpread(27, 3);
		int[] bottomIndices = ItemUtil.getIndiceArrayForSpread(30, 3);
		this.inventory.setAccessibleSideDefault(RelativeSide.TOP,
				RelativeSide.TOP, topIndices);
		this.inventory.setAccessibleSideDefault(RelativeSide.FRONT,
				RelativeSide.FRONT, frontIndices);// saplings
		this.inventory.setAccessibleSideDefault(RelativeSide.BOTTOM,
				RelativeSide.BOTTOM, bottomIndices);// bonemeal
		ItemSlotFilter filter = new ItemSlotFilter() {
			@Override
			public boolean isItemValid(ItemStack stack) {
				if (ItemStackTools.isNullStack(stack)) {
					return true;
				}
				if (stack.getItem() instanceof ItemBlock) {
					ItemBlock item = (ItemBlock) stack.getItem();
					return item.getBlock() instanceof BlockSapling || item.getBlock() instanceof BlockChorusFlower;
				}
				return false;
			}
		};
		this.inventory.setFilterForSlots(filter, frontIndices);
		filter = new ItemSlotFilter() {
			@Override
			public boolean isItemValid(ItemStack stack) {
				if (ItemStackTools.isNullStack(stack)) {
					return true;
				}

				if(isAxe(stack))
				{
					return true;
				}
				if(stack.getItem() instanceof ItemShears)
				{
					return true;
				}
				return stack.getItem() == Items.DYE
						&& stack.getItemDamage() == EnumDyeColor.WHITE.getDyeDamage();
			}
		};
		this.inventory.setFilterForSlots(filter, bottomIndices);
	}

	@Override
	public EnumSet<WorksiteUpgrade> getValidUpgrades()
	{
		return EnumSet.of(
				WorksiteUpgrade.SIZE_MEDIUM,
				WorksiteUpgrade.SIZE_LARGE,
				WorksiteUpgrade.BASIC_CHUNK_LOADER
				);
	}

	@Override
	public void onTargetsAdjusted() {
		validateCollection(blocksToFertilize);
		validateCollection(blocksToChop);
		validateCollection(blocksToPlant);
	}

	@Override
	public void onBoundsAdjusted() {
		validateCollection(blocksToFertilize);
		validateCollection(blocksToChop);
		validateCollection(blocksToPlant);
	}

	private void countResources() {
		shouldCountResources = false;
		saplingCount = 0;
		chorusFlowerCount = 0;
		bonemealCount = 0;
		ItemStack stack = ItemStackTools.getEmptyStack();
		for (int i = 27; i < 33; i++) {
			stack = inventory.getStackInSlot(i);
			if (!ItemStackTools.isValid(stack)) {
				continue;
			}
			if (stack.getItem() instanceof ItemBlock) {
				ItemBlock item = (ItemBlock) stack.getItem();
				if (item.getBlock() instanceof BlockSapling) {
					saplingCount += ItemStackTools.getStackSize(stack);
				}
				if (item.getBlock() instanceof BlockChorusFlower) {
					chorusFlowerCount += ItemStackTools.getStackSize(stack);
				}
			} else if (stack.getItem() == Items.DYE
					&& stack.getItemDamage() == EnumDyeColor.WHITE.getDyeDamage()) {
				bonemealCount += ItemStackTools.getStackSize(stack);
			}
		}
	}

	public static boolean isAxe(ItemStack axe){
		return ItemStackTools.isValid(axe) && ToolUtil.isAxe(axe) && !ToolUtil.isBrokenTinkerTool(axe) && !ToolUtil.isEmptyRfTool(axe);
	}

	public boolean giveAxe(EntityMinionWorker worker) {
		if(worker.getHeldItemMainhand().isEmpty()){
			int[] slots = this.inventory.getRawIndices(RelativeSide.BOTTOM);
			for(int i = 0; i < slots.length; i++){
				int slot = slots[i];
				ItemStack axe = inventory.getStackInSlot(slot);
				if(isAxe(axe)){
					worker.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, axe);
					this.inventory.setInventorySlotContents(slot, ItemStackTools.getEmptyStack());
					return true;
				}
			}
		}
		return false;
	}

	public boolean takeAxe(EntityMinionWorker worker) {
		if(ItemStackTools.isValid(worker.getHeldItemMainhand())){
			ItemStack held = worker.getHeldItemMainhand();
			if(ToolUtil.isBrokenTinkerTool(held) || ToolUtil.isEmptyRfTool(held)){
				if(addStackToInventoryNoDrop(held, false, RelativeSide.BOTTOM, RelativeSide.TOP)){
					worker.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, ItemStackTools.getEmptyStack());
					return true;
				}
			}
		}
		return false;
	}

	public WorkerFilter axeFilter = new WorkerFilter(){
		@Override
		public boolean matches(EntityMinionWorker worker) {
			ItemStack axe = worker.getHeldItemMainhand();
			return isAxe(axe);
		}
	};

	public WorkerFilter axeFilterBack = new WorkerFilter(){
		@Override
		public boolean matches(EntityMinionWorker worker) {
			ItemStack axe = worker.getBackItem();
			return isAxe(axe);
		}
	};

	public boolean isFoliage(IBlockState state){
		Block block = state.getBlock();
		return block instanceof BlockTallGrass || block instanceof BlockFlower || block instanceof BlockDoublePlant;
	}

	@SuppressWarnings("deprecation")
	@Override
	protected boolean processWork() {
		//Cleanup foliage
		if(bbMax != null && bbMin != null){
			int w = bbMax.getX() - bbMin.getX() + 1;
			int h = bbMax.getZ() - bbMin.getZ() + 1;
			BlockPos p;
			for (int x = 0; x < w; x++) {
				for (int z = 0; z < h; z++) {
					//not in bounds
					if (!isTarget(bbMin.getX() + x, bbMin.getZ() + z)) {
						p = bbMin.add(x, 0, z);
						IBlockState state = world.getBlockState(p);
						if(state.getBlock() instanceof BlockSapling || isFoliage(state)){
							junkBlocks.add(p);
						}
					}
				}
			}
		}

		BlockPos position;
		if(!junkBlocks.isEmpty()){
			Iterator<BlockPos> it = junkBlocks.iterator();
			while (it.hasNext() && (position = it.next()) != null) {
				if(busyBlocks.contains(position))continue;
				EntityMinionWorker worker = getClosestWorker(position, WorkerFilter.idleFilter);
				if (worker != null) {
					final BlockPos workPos = position;
					if(worker.addCommand(new JobDestoryBlock(position, true){
						@Override
						public void onCompleted(EntityMinionWorker worker, TileWorksiteBase worksite){
							busyBlocks.remove(workPos);
						}
					})){
						busyBlocks.add(workPos);
						it.remove();
						return true;
					}
				}
			}
		}
		if (!blocksToChop.isEmpty()) {
			Iterator<BlockPos> it = blocksToChop.iterator();
			while (it.hasNext() && (position = it.next()) != null) {
				if(busyBlocks.contains(position))continue;
				EntityMinionWorker worker = getClosestWorker(position, axeFilter, axeFilterBack, WorkerFilter.idleFilter);
				if (worker != null) {
					final BlockPos workPos = position;
					if(worker.addCommand(new JobChopTree(position){
						@Override
						public void onCompleted(EntityMinionWorker worker, TileWorksiteBase worksite){
							busyBlocks.remove(workPos);
						}
					})){
						busyBlocks.add(workPos);
						it.remove();
						return true;
					}
				}
			}
		} else if (saplingCount > 0 && !blocksToPlant.isEmpty()) {
			ItemStack stack = ItemStackTools.getEmptyStack();
			BlockSapling saplingBlock = null;
			int slot = 27;
			for (int i = 27; i < 30; i++) {
				stack = inventory.getStackInSlot(i);
				if (ItemStackTools.isValid(stack)
						&& stack.getItem() instanceof ItemBlock
						&& ((ItemBlock) stack.getItem()).getBlock() instanceof BlockSapling) {
					saplingBlock = (BlockSapling)((ItemBlock) stack.getItem()).getBlock();
					slot = i;
					break;
				} else {
					stack = ItemStackTools.getEmptyStack();
				}
			}
			if (ItemStackTools.isValid(stack))// e.g. a sapling stack is present
			{
				Iterator<BlockPos> it = blocksToPlant.iterator();
				while (it.hasNext() && (position = it.next()) != null) {
					if(busyBlocks.contains(position))continue;
					if (getWorld().isAirBlock(position) && canPlantSapling(position, saplingBlock)) {
						EntityMinionWorker worker = getClosestWorker(position, WorkerFilter.idleFilter);
						if(worker == null){
							//Look for workers with axes and use them
							EntityMinionWorker worker2 = getClosestWorker(position, axeFilter);
							if(worker2 !=null){
								worker2.switchItems();
								//Remove any odd items
								ItemStack held = worker2.getHeldItemMainhand();
								if(ItemStackTools.isValid(held)){
									addStackToInventory(held, RelativeSide.BOTTOM, RelativeSide.FRONT, RelativeSide.TOP);
									worker2.setHeldItem(EnumHand.MAIN_HAND, ItemStackTools.getEmptyStack());
								}
								worker = worker2;
							}
						}
						if(worker !=null){
							final BlockPos workPos = position;
							if(worker.addCommand(new JobPlantCrop(position){
								@Override
								public void onCompleted(EntityMinionWorker worker, TileWorksiteBase worksite){
									busyBlocks.remove(workPos);
								}
							})){
								busyBlocks.add(workPos);
								ItemStack copy = ItemUtil.copy(stack, 1);
								saplingCount--;
								inventory.decrStackSize(slot, 1);
								worker.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, copy);
								it.remove();
								return true;
							}
						}
					}
				}
			}
		} else if (chorusFlowerCount > 0 && !blocksToPlant.isEmpty()) {
			ItemStack stack = ItemStackTools.getEmptyStack();
			int slot = 27;
			for (int i = 27; i < 30; i++) {
				stack = inventory.getStackInSlot(i);
				if (ItemStackTools.isValid(stack)
						&& stack.getItem() instanceof ItemBlock
						&& ((ItemBlock) stack.getItem()).getBlock() instanceof BlockChorusFlower) {
					slot = i;
					break;
				} else {
					stack = ItemStackTools.getEmptyStack();
				}
			}
			if (ItemStackTools.isValid(stack))
			{
				Iterator<BlockPos> it = blocksToPlant.iterator();
				while (it.hasNext() && (position = it.next()) != null) {
					if(busyBlocks.contains(position))continue;
					if (getWorld().isAirBlock(position) && canPlantChorus(position)) {
						EntityMinionWorker worker = getClosestWorker(position, WorkerFilter.idleFilter);
						if(worker == null){
							//Look for workers with axes and use them
							EntityMinionWorker worker2 = getClosestWorker(position, axeFilter);
							if(worker2 !=null){
								worker2.switchItems();
								//Remove any odd items
								ItemStack held = worker2.getHeldItemMainhand();
								if(ItemStackTools.isValid(held)){
									addStackToInventory(held, RelativeSide.BOTTOM, RelativeSide.FRONT, RelativeSide.TOP);
									worker2.setHeldItem(EnumHand.MAIN_HAND, ItemStackTools.getEmptyStack());
								}
								worker = worker2;
							}
						}
						if(worker !=null){
							final BlockPos workPos = position;
							if(worker.addCommand(new JobPlantCrop(position){
								@Override
								public void onCompleted(EntityMinionWorker worker, TileWorksiteBase worksite){
									busyBlocks.remove(workPos);
								}
							})){
								busyBlocks.add(workPos);
								ItemStack copy = ItemUtil.copy(stack, 1);
								chorusFlowerCount--;
								inventory.decrStackSize(slot, 1);
								worker.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, copy);
								it.remove();
								return true;
							}
						}
					}
				}
			}
		} else if (bonemealCount > 0 && !blocksToFertilize.isEmpty()) {
			Iterator<BlockPos> it = blocksToFertilize.iterator();
			while (it.hasNext() && (position = it.next()) != null) {
				it.remove();
				IBlockState state = getWorld().getBlockState(position);
				if (state.getBlock() instanceof BlockSapling) {
					ItemStack stack = ItemStackTools.getEmptyStack();
					for (int i = 30; i < 33; i++) {
						stack = inventory.getStackInSlot(i);
						if (stack != null && stack.getItem() == Items.DYE
								&& stack.getItemDamage() == EnumDyeColor.WHITE.getDyeDamage()) {
							bonemealCount--;
							ItemDye.applyBonemeal(stack, getWorld(), position, FakePlayerUtil.getPlayer((WorldServer)getWorld()));
							if (ItemStackTools.isEmpty(stack)) {
								inventory.setInventorySlotContents(i, ItemStackTools.getEmptyStack());
							}
							state = getWorld().getBlockState(position);
							if (state.getBlock() instanceof BlockSapling) {
								blocksToFertilize.add(position);
							} else if (TreeUtil.isLog(state)) {
								blocksToChop.add(position);
							}
							return true;
						}
					}
					return false;
				}
			}
		}
		return false;
	}

	private boolean canPlantSapling(BlockPos pos, BlockSapling sapling){
		return sapling.canPlaceBlockAt(getWorld(), pos);
	}

	private boolean canPlantChorus(BlockPos pos){
		return Blocks.CHORUS_FLOWER.canPlaceBlockAt(getWorld(), pos);
	}

	private void pickupSaplings() {
		BlockPos p1 = getWorkBoundsMin();
		BlockPos p2 = getWorkBoundsMax().add(1, 1, 1);
		AxisAlignedBB bb = new AxisAlignedBB(p1, p2);
		List<EntityItem> items = getWorld().getEntitiesWithinAABB(EntityItem.class, bb);
		ItemStack stack;
		for (EntityItem item : items) {
			stack = item.getEntityItem();
			if (!ItemStackTools.isValid(stack)) {
				continue;
			}
			if (stack.getItem() == Items.APPLE) {
				item.setDead();
				addStackToInventory(stack, RelativeSide.TOP);
				continue;
			}
			if (stack.getItem() == Items.CHORUS_FRUIT) {
				item.setDead();
				addStackToInventory(stack, RelativeSide.TOP);
				continue;
			}
			if (stack.getItem() instanceof ItemBlock) {
				ItemBlock ib = (ItemBlock) stack.getItem();
				if (ib.getBlock() instanceof BlockSapling) {
					if (!ItemUtil.canInventoryHold(inventory, inventory
							.getRawIndicesCombined(RelativeSide.FRONT,
									RelativeSide.TOP), stack)) {
						break;
					}
					item.setDead();
					addStackToInventory(stack, RelativeSide.FRONT,
							RelativeSide.TOP);
				}
				if (ib.getBlock() instanceof BlockChorusFlower) {
					if (!ItemUtil.canInventoryHold(inventory, inventory
							.getRawIndicesCombined(RelativeSide.FRONT,
									RelativeSide.TOP), stack)) {
						break;
					}
					item.setDead();
					addStackToInventory(stack, RelativeSide.FRONT,
							RelativeSide.TOP);
				}
				if (TreeUtil.isLog(stack)) {
					if (!ItemUtil.canInventoryHold(inventory, inventory
							.getRawIndicesCombined(RelativeSide.TOP), stack)) {
						break;
					}
					item.setDead();
					addStackToInventory(stack, RelativeSide.TOP);
				}
			}
		}
	}

	public void manageAxes(){
		Iterator<EntityMinionWorker> iter = workers.iterator();
		while(iter.hasNext()){
			EntityMinionWorker worker = iter.next();
			if(worker !=null){
				takeAxe(worker);
			}
		}
	}

	private void addTreeBlocks(BlockPos base) {
		getWorld().theProfiler.startSection("TreeFinder");
		// TreeFinder.findAttachedTreeBlocks(getWorld().getBlock(base.x, base.y,
		// base.z), getWorld(), base.x, base.y, base.z, blocksToChop);
		blocksToChop.add(base);
		getWorld().theProfiler.endSection();
	}

	private void addChorusBlock(BlockPos base) {
		getWorld().theProfiler.startSection("ChorusFinder");
		//ModLogger.info("Found Chorus Plant");
		if(ChorusPlantUtil.isFullyGrownPlant(getWorld(), base))blocksToChop.add(base);
		getWorld().theProfiler.endSection();
	}

	@Override
	public WorkType getWorkType() {
		return WorkType.FORESTRY;
	}

	@Override
	public boolean onBlockClicked(EntityPlayer player) {
		if (!player.getEntityWorld().isRemote) {
			BlockUtil.openWorksiteGui(player, 0, getPos().getX(), getPos().getY(), getPos().getZ());
			return true;
		}
		return true;
	}

	@Override
	public void writeCustomNBT(NBTTagCompound tag) {
		super.writeCustomNBT(tag);
		if (!blocksToChop.isEmpty()) {
			NBTTagList chopList = new NBTTagList();
			NBTTagCompound posTag;
			for (BlockPos position : blocksToChop) {
				posTag = BlockUtil.saveBlockPos(position);
				chopList.appendTag(posTag);
			}
			tag.setTag("targetList", chopList);
		}
	}

	@Override
	public void readCustomNBT(NBTTagCompound tag) {
		super.readCustomNBT(tag);
		if (tag.hasKey("targetList")) {
			NBTTagList chopList = tag.getTagList("targetList",
					Constants.NBT.TAG_COMPOUND);
			for (int i = 0; i < chopList.tagCount(); i++) {
				NBTTagCompound posTag = chopList.getCompoundTagAt(i);
				blocksToChop.add(BlockUtil.loadBlockPos(posTag));
			}
		}
		this.shouldCountResources = true;
	}

	@Override
	protected void fillBlocksToProcess(Collection<BlockPos> targets) {
		if(bbMax == null || bbMin == null)return;
		int w = bbMax.getX() - bbMin.getX() + 1;
		int h = bbMax.getZ() - bbMin.getZ() + 1;
		BlockPos p;
		for (int x = 0; x < w; x++) {
			for (int z = 0; z < h; z++) {
				if (isTarget(bbMin.getX() + x, bbMin.getZ() + z)) {
					p = bbMin.add(x, 0, z);
					targets.add(p);
				}
			}
		}
	}

	@Override
	protected void scanBlockPosition(BlockPos pos) {
		IBlockState state;
		if (getWorld().isAirBlock(pos)) {
			state = getWorld().getBlockState(pos.down());
			//TODO handle canSustainPlant for saplings
			if (state.getBlock() == Blocks.DIRT || state.getBlock() == Blocks.GRASS || state.getBlock() == Blocks.END_STONE) {
				blocksToPlant.add(pos);
			}
		} else {
			state = getWorld().getBlockState(pos);
			if(isFoliage(state) && !junkBlocks.contains(pos)){
				junkBlocks.add(pos);
			}
			else if (state.getBlock() instanceof BlockSapling) {
				blocksToFertilize.add(pos);
			}
			else if (TreeUtil.isLog(state)) {
				if (!blocksToChop.contains(pos)) {
					addTreeBlocks(pos);
				}
			}else if (ChorusPlantUtil.isChorusPlant(state)) {
				if (!blocksToChop.contains(pos)) {
					addChorusBlock(pos);
				}
			}
		}
	}

	@Override
	protected boolean hasWorksiteWork() {
		return (bonemealCount > 0 && !blocksToFertilize.isEmpty())
				|| ((saplingCount > 0 || chorusFlowerCount > 0) && !blocksToPlant.isEmpty())
				|| !blocksToChop.isEmpty();
	}

	@Override
	protected void updateBlockWorksite() {
		getWorld().theProfiler.startSection("Count Resources");
		if (shouldCountResources) {
			countResources();
		}
		getWorld().theProfiler.endStartSection("SaplingPickup");
		if (getWorld().getWorldTime() % 20 == 0) {
			pickupSaplings();
		}
		getWorld().theProfiler.endStartSection("MinionAxe");
		if (getWorld().getWorldTime() % 20 == 0) {
			manageAxes();
		}
		getWorld().theProfiler.endSection();
	}

	@Override
	public boolean hasWork() {
		return hasWorksiteWork();
	}

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

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

	@Override
	public boolean isWorkerOkay(EntityMinionWorker minion) {
		return true;
	}

	@Override
	public boolean renderBounds() {
		return true;
	}

	private static final MultiHarvestComparator harvestComparator = new MultiHarvestComparator();
	public boolean chopDownTree(ItemStack stack, BlockPos pos)
    {
		if(getWorld().isRemote) return false;
		IBlockState state = getWorld().getBlockState(pos);
		Block block = state.getBlock();
		if(!TreeUtil.isLog(state)) return false;
		TreeHarvestUtil harvester = new TreeHarvestUtil();
		HarvestResult res = new HarvestResult();
		harvester.harvest(getWorld(), pos, res);

		List<BlockPos> sortedTargets = new ArrayList<BlockPos>(res.getHarvestedBlocks());
		harvestComparator.refPoint = pos;
		Collections.sort(sortedTargets, harvestComparator);

		boolean hasAxe = (ItemStackTools.isValid(stack) && !ToolUtil.isBrokenTinkerTool(stack) && !ToolUtil.isEmptyRfTool(stack));
		for(int i=0; hasAxe && i < sortedTargets.size();i++) {
			BlockPos bc = sortedTargets.get(i);
			IBlockState bs = getWorld().getBlockState(bc);
			int fourtune = EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, stack);
	  		if(fourtune < 2)fourtune += getUpgrades().contains(WorksiteUpgrade.ENCHANTED_TOOLS_1)? 1 : getUpgrades().contains(WorksiteUpgrade.ENCHANTED_TOOLS_2)? 2 : getUpgrades().contains(WorksiteUpgrade.ENCHANTED_TOOLS_3) ? 3 : 0;

	  		List<ItemStack> itemDrops = null;
	  		boolean sheared = false;
  			if(TreeHarvestUtil.isLeaves(bs, getWorld(), bc)){
	  			ItemStack shears = ItemStackTools.getEmptyStack();
	  			int[] slots = this.inventory.getRawIndices(RelativeSide.BOTTOM);
	  			slots : for(int s = 0; s < slots.length; s++){
					int slot = slots[s];
					ItemStack item = inventory.getStackInSlot(slot);
					if(item.getItem() instanceof ItemShears){
						shears = item;
						break slots;
					}
				}
	  			if(ItemStackTools.isValid(shears)){
	  				if(bs.getBlock() instanceof IShearable){
	  					itemDrops = ((IShearable)bs.getBlock()).onSheared(shears, getWorld(), bc, fourtune);
	  					getWorld().setBlockToAir(bc);
	  					if (shears.attemptDamageItem(1, getWorld().rand))
	  	                {
	  						shears.shrink(1);
	  	                }
	  					sheared = true;
	  				}
	  			}
	  		}
  			if(!sheared){
	  			itemDrops = TreeUtil.doMultiHarvest(stack, getWorld(), bc, block, fourtune);
	  		}
	  		for(ItemStack drop : itemDrops){
	  			addStackToInventory(drop, RelativeSide.FRONT, RelativeSide.TOP);
	  		}
	  		hasAxe = (ItemStackTools.isValid(stack) && !ToolUtil.isBrokenTinkerTool(stack) && !ToolUtil.isEmptyRfTool(stack));
		}
        return true;
    }

	public boolean chopDownChorus(ItemStack stack, BlockPos pos)
    {
		if(getWorld().isRemote) return false;
		IBlockState state = getWorld().getBlockState(pos);
		Block block = state.getBlock();
		if(!ChorusPlantUtil.isChorusPlant(state)) return false;
		ChorusPlantData data = ChorusPlantUtil.buildPlantData(getWorld(), pos);

		//Harvest Flowers First
		List<BlockPos> sortedTargets = new ArrayList<BlockPos>(data.flowerList);
		boolean hasAxe = (ItemStackTools.isValid(stack) && !ToolUtil.isBrokenTinkerTool(stack) && !ToolUtil.isEmptyRfTool(stack));
		for(int i=0; hasAxe && i < sortedTargets.size(); i++) {
			BlockPos bc = sortedTargets.get(i);
			ItemStack flowerStack = new ItemStack(Blocks.CHORUS_FLOWER);
			getWorld().playEvent(2001, bc, Block.getStateId(state));
			getWorld().setBlockToAir(bc);
		    addStackToInventory(flowerStack, RelativeSide.FRONT, RelativeSide.TOP);
	  		hasAxe = (ItemStackTools.isValid(stack) && !ToolUtil.isBrokenTinkerTool(stack) && !ToolUtil.isEmptyRfTool(stack));
		}

		//Now harvest plant
		hasAxe = (ItemStackTools.isValid(stack) && !ToolUtil.isBrokenTinkerTool(stack) && !ToolUtil.isEmptyRfTool(stack));
		sortedTargets = new ArrayList<BlockPos>(data.plantList);
		harvestComparator.refPoint = pos;
		Collections.sort(sortedTargets, harvestComparator);
		for(int i=0; hasAxe && i < sortedTargets.size();i++) {
			BlockPos bc = sortedTargets.get(i);
			int fourtune = EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, stack);
	  		if(fourtune < 2)fourtune += getUpgrades().contains(WorksiteUpgrade.ENCHANTED_TOOLS_1)? 1 : getUpgrades().contains(WorksiteUpgrade.ENCHANTED_TOOLS_2)? 2 : getUpgrades().contains(WorksiteUpgrade.ENCHANTED_TOOLS_3) ? 3 : 0;

	  		List<ItemStack> itemDrops = TreeUtil.doMultiHarvest(stack, getWorld(), bc, block, fourtune);
	  		for(ItemStack drop : itemDrops){
	  			addStackToInventory(drop, RelativeSide.FRONT, RelativeSide.TOP);
	  		}
	  		hasAxe = (ItemStackTools.isValid(stack) && !ToolUtil.isBrokenTinkerTool(stack) && !ToolUtil.isEmptyRfTool(stack));
		}
        return true;
    }

}


text:
require('reflect-metadata');
require('traceur/bin/traceur-runtime');
module.exports = require('./benchpress.js');
// when bundling benchpress to one file, this is used
// for getting exports out of browserify's scope.
(<any>global).__benchpressExports = module.exports;


text:
package com.github.chrisgleissner.behaim.builder.producer;

import com.github.chrisgleissner.behaim.builder.adapter.EnumAdapter;
import com.github.chrisgleissner.behaim.builder.adapter.SeedAdapter;
import com.github.chrisgleissner.behaim.builder.config.Config;
import com.github.chrisgleissner.behaim.builder.config.FieldConfig;
import com.github.chrisgleissner.behaim.builder.seeder.RandomSeeder;
import com.github.chrisgleissner.behaim.builder.seeder.SequentialSeeder;
import com.github.chrisgleissner.behaim.domain.ColorEnum;
import com.github.chrisgleissner.behaim.explorer.FieldUtil;
import com.github.chrisgleissner.behaim.utils.PersonFields;
import org.junit.Test;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;

import java.lang.reflect.Field;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;

/**
 * @author Fabien DUMINY
 */
@RunWith(Theories.class)
public class ProducerVisitorContextTest {
    @Theory
    public void getFieldContextFor_enumField(boolean random) throws Exception {
        Field field = PersonFields.PREFERRED_COLOR.getField();
        FieldConfig fieldConfig = mock(FieldConfig.class);
        when(fieldConfig.isRandom()).thenReturn(random);
        Config config = mock(Config.class);
        String fieldName = FieldUtil.getNameFor(field);
        when(config.getFieldConfigFor(eq(fieldName))).thenReturn(fieldConfig);
        ProducerVisitorContext visitorContext = new ProducerVisitorContext(config);

        ProducerFieldContext fieldContext = visitorContext.getFieldContextFor(field);

        verify(config).getFieldConfigFor(eq(fieldName));
        verify(fieldConfig).isRandom();
        verifyNoMoreInteractions(config, fieldConfig);
        assertThat(fieldContext).as("result").isNotNull();
        assertThat(fieldContext.getField()).as("result.field").isSameAs(field);
        assertThat(fieldContext.getSeeder()).as("result.seeder").isInstanceOf(random ? RandomSeeder.class : SequentialSeeder.class);
        FieldConfig actualConfig = fieldContext.getSeeder().getConfig();
        assertThat(actualConfig).as("actualConfig").isNotNull().isNotSameAs(fieldConfig);
        assertThat(actualConfig.getMinValue()).as("actualConfig.minValue").isEqualTo(0);
        assertThat(actualConfig.getMaxValue()).as("actualConfig.maxValue").isEqualTo(ColorEnum.values().length);
        assertThat(actualConfig.isRandom()).as("actualConfig.random").isEqualTo(random);
    }

    @Test
    public void getSeedAdapterFor() throws Exception {
        Config config = mock(Config.class);
        ProducerVisitorContext visitorContext = new ProducerVisitorContext(config);

        SeedAdapter<?> seedAdapter = visitorContext.getSeedAdapterFor(PersonFields.PREFERRED_COLOR.getField());

        assertThat(seedAdapter).as("result").isInstanceOf(EnumAdapter.class);
        EnumAdapter enumAdapter = (EnumAdapter) seedAdapter;
        assertThat(enumAdapter.getValueClass()).isSameAs(ColorEnum.class);
        verifyNoMoreInteractions(config);
    }
}


text:
<?php
/**
 * Created by PhpStorm.
 * User: Nomad_Mystic
 * Date: 11/5/2015
 * Time: 12:51 AM
 */

define('COUNTRY_FIELD', 0);

const INCLUDES_FOLDER = 'includes';

////LOOPS AND USER INPUT
const NUMBER_COUNTRIES = 227;
const YEARS = 29;
const CHOSEN_COUNTRY_KEY_1 = 'user_input_1';
const CHOSEN_COUNTRY_KEY_2 = 'user_input_2';

// FILES AND PATHWAYS
const TARGET_PAGE = 'country_consumption.php';
const STYLES = 'coal_styles.css.php';
const STYLES_PATH = INCLUDES_FOLDER . '/' . STYLES;

const MAP_IMAGE = 'world_map.jpg';
const IMAGE_FOLDER = 'images';
const MAP_PICTURE_PATH = IMAGE_FOLDER . '/' . MAP_IMAGE;

const LIB = 'lib/';
const FONT_AWESOME_PATH = 'font-awesome.css';
const BOOTSTRAP_CSS_PATH = 'bootstrap.min.css';
const BOOTSTRAP_JS_PATH = 'bootstrap.min.js';
const JQUERY_PATH = 'jquery.min.js';

const CHART_JS_PATH = 'Chart.min.js';
const CUSTOM_JS_PATH = 'includes/coal.js.php';

//// STYLES
const FLOAT_DIRECTION = 'left';
const FLOAT_WIDTH = '45';

const BLUE_BACKGROUND = '#00FFFF';
const WHITE_BACKGROUND = 'rgba(255,255,255,.5)';
const BORDER_RADIUS = '4px';
const TEXT_PADDING = '2';
const BORDER = 'solid rgba(0,0,0,.25) 4px';
const BASE_FONT_SIZE = '1.25';