SpacesAroundOperatorsRule = {};

SpacesAroundOperatorsRule.name = 'SpacesAroundOperators';

var operators = [ '||', '&&', '^', '|', '&', '==', '!=', '===', '!==', '<', '>', '<=', '>=',
                  '<<', '>>', '>>>', '+', '-', '*', '%', '/',
                  '+=', '-=', '*=', '%=', '&=', '|=', '^=', '/=', '=' ];

SpacesAroundOperatorsRule.infer = function (sample, callback) {
    var previousToken = null,
        spaces = {};
    
    sample.on('data', function (token) {
        if (token.type === 'Punctuator' && operators.indexOf(token.value) !== -1) {
            if (typeof spaces[token.value] === 'undefined')
                spaces[token.value] = { present: 0, omitted: 0, count: 0 };
            if (previousToken && previousToken.type === 'Whitespaces') {
                if (previousToken.value === ' ')
                    spaces[token.value].present++;
            } else {
                spaces[token.value].omitted++;
            }
            spaces[token.value].count++;
        }
        previousToken = token;
    });
    sample.on('end', function () {
        var value = {};
        for (var character in spaces) {
            var characterValue = spaces[character],
                max = Math.max(characterValue.present, characterValue.omitted,
                               characterValue.count - characterValue.present - characterValue.omitted);

            if (max === characterValue.present)
                value[character] = 'present';
            else if (max === characterValue.omitted)
                value[character] = 'omitted';
            else
                value[character] = null;
        }
        callback(null, value);
    });
};

SpacesAroundOperatorsRule.transform = function (input, value, output, callback) {
    var previousToken = null,
        space = { type: 'Whitespaces', value: ' ' };

    input.on('data', function (token) {
        if (token.type === 'Whitespaces') {
            if (previousToken && previousToken.type === 'Punctuator'
                && operators.indexOf(previousToken.value) !== -1
                && (value === 'omitted' || value[previousToken.value] === 'omitted')
                && token.value === ' ')
                token.value = '';
        } else if (token.type === 'Punctuator' && operators.indexOf(token.value) !== -1) {
            if (previousToken && previousToken.type === 'Whitespaces') {
                if (previousToken.value !== ' '
                    || value === 'present'
                    || value[token.value] === 'present')
                    output.write(previousToken);
            }
            output.write(token);
        } else {
            if (previousToken && previousToken.type === 'Whitespaces')
                output.write(previousToken);
            output.write(token);
        }
        previousToken = token;
    });
    input.on('end', function () {
        if (previousToken.type === 'Whitespaces')
            output.write(previousToken);
        output.end();
        callback(null);
    });
};

module.exports = SpacesAroundOperatorsRule;

@@ -1848,135 +1848,220 @@
  %7D;%0A
+    
 %0A    
-input.on('data', function (token) %7B%0A        if (token.type === 'Whitespaces') %7B%0A            if (previousToken && previousT
+function shouldUseSpaces(operator) %7B%0A        if (typeof value === 'object')%0A            return value%5Boperator%5D;%0A        return value;%0A    %7D%0A    %0A    function isOperator(token) %7B%0A        return token && t
 oken
@@ -2082,32 +2082,16 @@
 ctuator'
-%0A               
  && oper
@@ -2104,25 +2104,17 @@
 indexOf(
-previousT
+t
 oken.val
@@ -2127,113 +2127,234 @@
 = -1
+;
 %0A    
+%7D%0A
     
+%0A
     
-    && (value === 'omitted' %7C%7C value%5BpreviousToken.value%5D === 'omitted')%0A                && 
+input.on('data', function (token) %7B%0A        if (isOperator(token)) %7B%0A            if (previousToken && previousToken.type === 'Whitespaces') %7B%0A                if (previousToken.value !== ' ' %7C%7C shouldUseSpaces(
 toke
@@ -2352,39 +2352,46 @@
 aces(token.value
- =
+) !
 == '
- 
+omitted
 ')%0A             
@@ -2397,159 +2397,259 @@
     
+ 
-token.value = '';%0A        %7D else if (token.type === 'Punctuator' && operators.indexOf(token.value) !== -1) %7B%0A            if (previousToken && previousT
+   output.write(previousToken);%0A            %7D else if (shouldUseSpaces(token.value) === 'present') %7B%0A                output.write(space);%0A            %7D%0A            output.write(token);%0A        %7D else if (isOperator(previousToken)) %7B%0A            if (t
 oken
@@ -2686,32 +2686,71 @@
              if 
+(token.value === ' ' && shouldUseSpaces
 (previousToken.v
@@ -2753,24 +2753,32 @@
 en.value
- !
+) =
 == '
- '
+omitted')
 %0A       
@@ -2794,30 +2794,25 @@
     
-%7C%7C 
+token.
 value =
-==
  '
-present
 '
+;
 %0A   
@@ -2824,26 +2824,44 @@
     
-        %7C%7C value%5Bt
+%7D else if (shouldUseSpaces(previousT
 oken
@@ -2862,25 +2862,25 @@
 sToken.value
-%5D
+)
  === 'presen
@@ -2882,16 +2882,18 @@
 resent')
+ %7B
 %0A       
@@ -2893,36 +2893,32 @@
                 
-    
 output.write(pre
@@ -2918,38 +2918,20 @@
 ite(
-previousToken
+space
 );%0A    
-        %7D%0A
     
@@ -2951,32 +2951,46 @@
 t.write(token);%0A
+            %7D%0A
         %7D else %7B
@@ -3098,32 +3098,82 @@
 previousToken);%0A
+            if (token.type !== 'Whitespaces')%0A    
             outp

Simplify the operator whitespace logic a bit