text:
'use strict';

/* TODO: Add tests for:
 • Whitespace preservation in messages.
 • Whitespace ignored around syntax except for offset:N.
 • Escaping for curlies and the # symbol.
 • # symbol value.
 • # symbol value when gender is nested inside plural.
 • Error with nested # symbol.
 • parser error messages.
 • caching.
 • watched expressions.
 • test parsing angular expressions
 • test the different regexes
 • test the different starting rules
*/

describe('$$ngMessageFormat', function() {
  describe('core', function() {
    var $$messageFormat, $parse, $interpolate, $locale, $rootScope;

    function Person(name, gender) {
      this.name = name;
      this.gender = gender;
    }

    var alice   = new Person("Alice", "female"),
        bob     = new Person("Bob", "male"),
        charlie = new Person("Charlie", "male"),
        harry   = new Person("Harry Potter", "male");

    function initScope($scope) {
      $scope.recipients = [alice, bob, charlie];
      $scope.sender = harry;
    }

    beforeEach(module('ngMessageFormat'));

    beforeEach(function() {
      inject(['$$messageFormat', '$parse', '$locale', '$interpolate', '$rootScope', function(
                 messageFormat,    parse,    locale,    interpolate,    rootScope) {
        $$messageFormat = messageFormat;
        $parse = parse;
        $interpolate = interpolate;
        $locale = locale;
        $rootScope = rootScope;
        initScope(rootScope);
      }]);
    });

    describe('mustache', function() {
      function assertMustache(text, expected) {
        var parsedFn = $interpolate(text);
        expect(parsedFn($rootScope)).toEqual(expected);
      }

      it('should suppress falsy objects', function() {
        assertMustache("{{undefined}}", "");
        assertMustache("{{null}}", "");
        assertMustache("{{a.b}}", "");
      });

      it('should jsonify objects', function() {
        assertMustache("{{ {} }}", "{}");
        assertMustache("{{ true }}", "true");
        assertMustache("{{ false }}", "false");
        assertMustache("{{ 1 }}", "1");
        assertMustache("{{ '1' }}", "1");
        assertMustache("{{ sender }}", '{"name":"Harry Potter","gender":"male"}');
      });

      it('should return function that can be called with no context', inject(function($interpolate) {
        expect($interpolate("{{sender.name}}")()).toEqual("");
      }));

      describe('watchable', function() {
        it('ckck', function() {
          var calls = [];
          $rootScope.$watch($interpolate("{{::name}}"), function(val) {
            calls.push(val);
          });

          $rootScope.$apply();
          expect(calls.length).toBe(1);

          $rootScope.name = "foo";
          $rootScope.$apply();
          expect(calls.length).toBe(2);
          expect(calls[1]).toBe('foo');

          $rootScope.name = "bar";
          $rootScope.$apply();
          expect(calls.length).toBe(2);
        });

        it('should stop watching strings with no expressions after first execution', function() {
          var spy = jasmine.createSpy();
          $rootScope.$watch($$messageFormat.interpolate('foo'), spy);
          $rootScope.$digest();
          expect($rootScope.$countWatchers()).toBe(0);
          expect(spy).toHaveBeenCalledWith('foo', 'foo', $rootScope);
          expect(spy).toHaveBeenCalledTimes(1);
        });

        it('should stop watching strings with only constant expressions after first execution', function() {
          var spy = jasmine.createSpy();
          $rootScope.$watch($$messageFormat.interpolate('foo {{42}}'), spy);
          $rootScope.$digest();
          expect($rootScope.$countWatchers()).toBe(0);
          expect(spy).toHaveBeenCalledWith('foo 42', 'foo 42', $rootScope);
          expect(spy).toHaveBeenCalledTimes(1);
        });

      });

      describe('plural', function() {
        it('no interpolation', function() {
          var text = "" +
            "{{recipients.length, plural,\n" +
            "    =0    {You gave no gifts}\n" +
            "    =1    {You gave one person a gift}\n" +
            // "=1" should override "one" for exact value.
            "    one   {YOU SHOULD NEVER SEE THIS MESSAGE}\n" +
            "    other {You gave some people gifts}\n" +
            "}}";
          var parsedFn = $interpolate(text, /*mustHaveExpression=*/true);
          expect(parsedFn.expressions.length).toBe(1);
          expect(parsedFn.expressions[0]).toEqual("recipients.length");

          $rootScope.recipients.length=2;
          expect(parsedFn($rootScope)).toEqual("You gave some people gifts");

          $rootScope.recipients.length=1;
          expect(parsedFn($rootScope)).toEqual("You gave one person a gift");

          $rootScope.recipients.length=0;
          expect(parsedFn($rootScope)).toEqual("You gave no gifts");
        });

        it('with interpolation', function() {
          var text = "" +
            "{{recipients.length, plural,\n" +
            "    =0    {{{sender.name}} gave no gifts}\n" +
            "    =1    {{{sender.name}} gave one gift to {{recipients[0].name}}}\n" +
            // "=1" should override "one" for exact value.
            "    one   {YOU SHOULD NEVER SEE THIS MESSAGE}\n" +
            "    other {{{sender.name}} gave them a gift}\n" +
            "}}";
          var parsedFn = $interpolate(text, /*mustHaveExpression=*/true);
          expect(parsedFn.expressions.length).toBe(1);
          expect(parsedFn.expressions[0]).toEqual("recipients.length");

          $rootScope.recipients.length=2;
          expect(parsedFn($rootScope)).toEqual("Harry Potter gave them a gift");

          $rootScope.recipients.length=1;
          expect(parsedFn($rootScope)).toEqual("Harry Potter gave one gift to Alice");

          $rootScope.recipients.length=0;
          expect(parsedFn($rootScope)).toEqual("Harry Potter gave no gifts");
        });

        it('with offset, interpolation, "#" symbol with and without escaping', function() {
          var text = "" +
            "{{recipients.length, plural, offset:1\n" +
            // NOTE: It's nonsensical to use "#" for "=0" with a positive offset.
            "    =0    {{{sender.name}} gave no gifts (\\#=#)}\n" +
            "    =1    {{{sender.name}} gave one gift to {{recipients[0].name}} (\\#=#)}\n" +
            "    one   {{{sender.name}} gave {{recipients[0].name}} and one other person a gift (\\#=#)}\n" +
            "    other {{{sender.name}} gave {{recipients[0].name}} and # other people a gift (\\#=#)}\n" +
            "}}";
          var parsedFn = $interpolate(text, /*mustHaveExpression=*/true);
          expect(parsedFn.expressions.length).toBe(1);
          expect(parsedFn.expressions[0]).toEqual("recipients.length");

          $rootScope.recipients.length=3;
          // "#" should get replaced with the value of "recipients.length - offset"
          expect(parsedFn($rootScope)).toEqual("Harry Potter gave Alice and 2 other people a gift (#=2)");

          $rootScope.recipients.length=2;
          expect(parsedFn($rootScope)).toEqual("Harry Potter gave Alice and one other person a gift (#=1)");

          $rootScope.recipients.length=1;
          expect(parsedFn($rootScope)).toEqual("Harry Potter gave one gift to Alice (#=0)");

          $rootScope.recipients.length=0;
          expect(parsedFn($rootScope)).toEqual("Harry Potter gave no gifts (#=-1)");
        });
      });

      it('nested plural and select', function() {
        var text = "" +
          "{{recipients.length, plural,\n" +
          "    =0 {You gave no gifts}\n" +
          "    =1 {{{recipients[0].gender, select,\n" +
          "            male {You gave him a gift. -{{sender.name}}}\n" +
          "            female {You gave her a gift. -{{sender.name}}}\n" +
          "            other {You gave them a gift. -{{sender.name}}}\n" +
          "        }}\n" +
          "       }\n" +
          "    other {You gave {{recipients.length}} people gifts. -{{sender.name}}}\n" +
          "}}";
        var parsedFn = $interpolate(text, /*mustHaveExpression=*/true);
        expect(parsedFn.expressions.length).toBe(1);
        expect(parsedFn.expressions[0]).toEqual("recipients.length");
        var result = parsedFn($rootScope);
        expect(result).toEqual("You gave 3 people gifts. -Harry Potter");
      });
    });

    describe('interpolate', function() {
      function assertInterpolation(text, expected) {
        var parsedFn = $$messageFormat.interpolate(text);
        expect(parsedFn($rootScope)).toEqual(expected);
      }

      it('should interpolate a plain string', function() {
        assertInterpolation(" Hello, world! ", " Hello, world! ");
      });

      it('should interpolate a simple expression', function() {
        assertInterpolation("Hello, {{sender.name}}!", "Hello, Harry Potter!");
      });
    });
  });

  /* NOTE: This describe block includes a copy of interpolateSpec.js to test that
   *       $$messageFormat.interpolate behaves the same as $interpolate.
   *       ONLY the following changes have been made.
   *       - Add beforeEach(module('ngMessageFormat')) at top level of describe()
   *       - Add extra "}" for it('should not unescape markers within expressions'). Original
   *         $interpolate has a bug/feature where a "}}" inside a string is also treated as a
   *         closing symbol.  The new service understands the string context and fixes this.
   *       - All tests for startSymbol/endSymbol have been commented out.  The new service does not
   *         allow you to change them as of now.
   *       - Instead, I've added tests to assert that we throw an exception if used with redefined
   *         startSymbol/endSymbol.  These tests are listed right in the beginning before the
   *         others.  allow you to change them as of now.
   */
  describe('$interpolate', function() {
    beforeEach(module('ngMessageFormat'));

    describe('startSymbol', function() {
      it('should expose the startSymbol in run phase', inject(function($interpolate) {
        expect($interpolate.startSymbol()).toBe('{{');
      }));
      describe('redefinition', function() {
        beforeEach(module(function($interpolateProvider) {
          expect($interpolateProvider.startSymbol()).toBe('{{');
          $interpolateProvider.startSymbol('((');
        }));
        it('should not work when the startSymbol is redefined', function() {
          expect(function() {
            inject(inject(function($interpolate) {}));
          }).toThrowMinErr('$interpolate', 'nochgmustache');
        });
      });
    });

    describe('endSymbol', function() {
      it('should expose the endSymbol in run phase', inject(function($interpolate) {
        expect($interpolate.endSymbol()).toBe('}}');
      }));
      describe('redefinition', function() {
        beforeEach(module(function($interpolateProvider) {
          expect($interpolateProvider.endSymbol()).toBe('}}');
          $interpolateProvider.endSymbol('))');
        }));
        it('should not work when the endSymbol is redefined', function() {
          expect(function() {
            inject(inject(function($interpolate) {}));
          }).toThrowMinErr('$interpolate', 'nochgmustache');
        });
      });
    });

    it('should return the interpolation object when there are no bindings and textOnly is undefined',
        inject(function($interpolate) {
      var interpolateFn = $interpolate('some text');

      expect(interpolateFn.exp).toBe('some text');
      expect(interpolateFn.expressions).toEqual([]);

      expect(interpolateFn({})).toBe('some text');
    }));

    it('should return undefined when there are no bindings and textOnly is set to true',
        inject(function($interpolate) {
      expect($interpolate('some text', true)).toBeUndefined();
    }));

    it('should return undefined when there are bindings and strict is set to true',
        inject(function($interpolate) {
      expect($interpolate('test {{foo}}', false, null, true)({})).toBeUndefined();
    }));

    it('should suppress falsy objects', inject(function($interpolate) {
      expect($interpolate('{{undefined}}')({})).toEqual('');
      expect($interpolate('{{null}}')({})).toEqual('');
      expect($interpolate('{{a.b}}')({})).toEqual('');
    }));

    it('should jsonify objects', inject(function($interpolate) {
      expect($interpolate('{{ {} }}')({})).toEqual('{}');
      expect($interpolate('{{ true }}')({})).toEqual('true');
      expect($interpolate('{{ false }}')({})).toEqual('false');
    }));

    it('should use custom toString when present', inject(function($interpolate, $rootScope) {
       var context = {
        a: {
          toString: function() {
            return 'foo';
          }
        }
      };

      expect($interpolate('{{ a }}')(context)).toEqual('foo');
    }));

    it('should NOT use toString on array objects', inject(function($interpolate) {
      expect($interpolate('{{a}}')({ a: [] })).toEqual('[]');
    }));

    it('should NOT use toString on Date objects', inject(function($interpolate) {
      var date = new Date(2014, 10, 10);
      expect($interpolate('{{a}}')({ a: date })).toBe(JSON.stringify(date));
      expect($interpolate('{{a}}')({ a: date })).not.toEqual(date.toString());
    }));

    it('should return interpolation function', inject(function($interpolate, $rootScope) {
      var interpolateFn = $interpolate('Hello {{name}}!');

      expect(interpolateFn.exp).toBe('Hello {{name}}!');
      expect(interpolateFn.expressions).toEqual(['name']);

      var scope = $rootScope.$new();
      scope.name = 'Bubu';

      expect(interpolateFn(scope)).toBe('Hello Bubu!');
    }));

    it('should ignore undefined model', inject(function($interpolate) {
      expect($interpolate("Hello {{'World'}}{{foo}}")({})).toBe('Hello World');
    }));

    it('should interpolate with undefined context', inject(function($interpolate) {
      expect($interpolate("Hello, world!{{bloop}}")()).toBe("Hello, world!");
    }));

    describe('watching', function() {
      it('should be watchable with any input types', inject(function($interpolate, $rootScope) {
        var lastVal;
        $rootScope.$watch($interpolate('{{i}}'), function(val) {
          lastVal = val;
        });
        $rootScope.$apply();
        expect(lastVal).toBe('');

        $rootScope.i = null;
        $rootScope.$apply();
        expect(lastVal).toBe('');

        $rootScope.i = '';
        $rootScope.$apply();
        expect(lastVal).toBe('');

        $rootScope.i = 0;
        $rootScope.$apply();
        expect(lastVal).toBe('0');

        $rootScope.i = [0];
        $rootScope.$apply();
        expect(lastVal).toBe('[0]');

        $rootScope.i = {a: 1, b: 2};
        $rootScope.$apply();
        expect(lastVal).toBe('{"a":1,"b":2}');
      }));

      it('should be watchable with literal values', inject(function($interpolate, $rootScope) {
        var lastVal;
        $rootScope.$watch($interpolate('{{1}}{{"2"}}{{true}}{{[false]}}{{ {a: 2} }}'), function(val) {
          lastVal = val;
        });
        $rootScope.$apply();
        expect(lastVal).toBe('12true[false]{"a":2}');

        expect($rootScope.$countWatchers()).toBe(0);
      }));

      it('should respect one-time bindings for each individual expression', inject(function($interpolate, $rootScope) {
        var calls = [];
        $rootScope.$watch($interpolate('{{::a | limitTo:1}} {{::s}} {{::i | number}}'), function(val) {
          calls.push(val);
        });

        $rootScope.$apply();
        expect(calls.length).toBe(1);

        $rootScope.a = [1];
        $rootScope.$apply();
        expect(calls.length).toBe(2);
        expect(calls[1]).toBe('[1]  ');

        $rootScope.a = [0];
        $rootScope.$apply();
        expect(calls.length).toBe(2);

        $rootScope.i = $rootScope.a = 123;
        $rootScope.s = 'str!';
        $rootScope.$apply();
        expect(calls.length).toBe(3);
        expect(calls[2]).toBe('[1] str! 123');

        expect($rootScope.$countWatchers()).toBe(0);
      }));

      it('should stop watching strings with no expressions after first execution',
        inject(function($interpolate, $rootScope) {
          var spy = jasmine.createSpy();
          $rootScope.$watch($interpolate('foo'), spy);
          $rootScope.$digest();
          expect($rootScope.$countWatchers()).toBe(0);
          expect(spy).toHaveBeenCalledWith('foo', 'foo', $rootScope);
          expect(spy).toHaveBeenCalledTimes(1);
        })
      );

      it('should stop watching strings with only constant expressions after first execution',
        inject(function($interpolate, $rootScope) {
          var spy = jasmine.createSpy();
          $rootScope.$watch($interpolate('foo {{42}}'), spy);
          $rootScope.$digest();
          expect($rootScope.$countWatchers()).toBe(0);
          expect(spy).toHaveBeenCalledWith('foo 42', 'foo 42', $rootScope);
          expect(spy).toHaveBeenCalledTimes(1);
        })
      );
    });

    describe('interpolation escaping', function() {
      var obj;
      beforeEach(function() {
        obj = {foo: 'Hello', bar: 'World'};
      });

      it('should support escaping interpolation signs', inject(function($interpolate) {
        expect($interpolate('{{foo}} \\{\\{bar\\}\\}')(obj)).toBe('Hello {{bar}}');
        expect($interpolate('\\{\\{foo\\}\\} {{bar}}')(obj)).toBe('{{foo}} World');
      }));

      it('should unescape multiple expressions', inject(function($interpolate) {
        expect($interpolate('\\{\\{foo\\}\\}\\{\\{bar\\}\\} {{foo}}')(obj)).toBe('{{foo}}{{bar}} Hello');
        expect($interpolate('{{foo}}\\{\\{foo\\}\\}\\{\\{bar\\}\\}')(obj)).toBe('Hello{{foo}}{{bar}}');
        expect($interpolate('\\{\\{foo\\}\\}{{foo}}\\{\\{bar\\}\\}')(obj)).toBe('{{foo}}Hello{{bar}}');
        expect($interpolate('{{foo}}\\{\\{foo\\}\\}{{bar}}\\{\\{bar\\}\\}{{foo}}')(obj)).toBe('Hello{{foo}}World{{bar}}Hello');
      }));

      /*
       *it('should support escaping custom interpolation start/end symbols', function() {
       *  module(function($interpolateProvider) {
       *    $interpolateProvider.startSymbol('[[');
       *    $interpolateProvider.endSymbol(']]');
       *  });
       *  inject(function($interpolate) {
       *    expect($interpolate('[[foo]] \\[\\[bar\\]\\]')(obj)).toBe('Hello [[bar]]');
       *  });
       *});
       */

      it('should unescape incomplete escaped expressions', inject(function($interpolate) {
        expect($interpolate('\\{\\{foo{{foo}}')(obj)).toBe('{{fooHello');
        expect($interpolate('\\}\\}foo{{foo}}')(obj)).toBe('}}fooHello');
        expect($interpolate('foo{{foo}}\\{\\{')(obj)).toBe('fooHello{{');
        expect($interpolate('foo{{foo}}\\}\\}')(obj)).toBe('fooHello}}');
      }));

      it('should not unescape markers within expressions', inject(function($interpolate) {
        expect($interpolate('{{"\\\\{\\\\{Hello, world!\\\\}\\\\}"}}')(obj)).toBe('\\{\\{Hello, world!\\}\\}');
        expect($interpolate('{{"\\{\\{Hello, world!\\}\\}"}}')(obj)).toBe('{{Hello, world!}}');
        expect(function() {
          $interpolate('{{\\{\\{foo\\}\\}}}')(obj);
        }).toThrowMinErr('$parse', 'lexerr',
          'Lexer Error: Unexpected next character  at columns 0-0 [\\] in expression [\\{\\{foo\\}\\}]');
      }));

      // This test demonstrates that the web-server is responsible for escaping every single instance
      // of interpolation start/end markers in an expression which they do not wish to evaluate,
      // because AngularJS will not protect them from being evaluated (due to the added complexity
      // and maintenance burden of context-sensitive escaping)
      it('should evaluate expressions between escaped start/end symbols', inject(function($interpolate) {
        expect($interpolate('\\{\\{Hello, {{bar}}!\\}\\}')(obj)).toBe('{{Hello, World!}}');
      }));
    });

    describe('interpolating in a trusted context', function() {
      var sce;
      beforeEach(function() {
        function log() {}
        var fakeLog = {log: log, warn: log, info: log, error: log};
        module(function($provide, $sceProvider) {
          $provide.value('$log', fakeLog);
          $sceProvider.enabled(true);
        });
        inject(['$sce', function($sce) { sce = $sce; }]);
      });

      it('should NOT interpolate non-trusted expressions', inject(function($interpolate, $rootScope) {
        var scope = $rootScope.$new();
        scope.foo = "foo";

        expect(function() {
          $interpolate('{{foo}}', true, sce.CSS)(scope);
        }).toThrowMinErr('$interpolate', 'interr');
      }));

      it('should NOT interpolate mistyped expressions', inject(function($interpolate, $rootScope) {
        var scope = $rootScope.$new();
        scope.foo = sce.trustAsCss("foo");

        expect(function() {
          $interpolate('{{foo}}', true, sce.HTML)(scope);
        }).toThrowMinErr('$interpolate', 'interr');
      }));

      it('should interpolate trusted expressions in a regular context', inject(function($interpolate) {
        var foo = sce.trustAsCss("foo");
        expect($interpolate('{{foo}}', true)({foo: foo})).toBe('foo');
      }));

      it('should interpolate trusted expressions in a specific trustedContext', inject(function($interpolate) {
        var foo = sce.trustAsCss("foo");
        expect($interpolate('{{foo}}', true, sce.CSS)({foo: foo})).toBe('foo');
      }));

      // The concatenation of trusted values does not necessarily result in a trusted value.  (For
      // instance, you can construct evil JS code by putting together pieces of JS strings that are by
      // themselves safe to execute in isolation.)
      it('should NOT interpolate trusted expressions with multiple parts', inject(function($interpolate) {
        var foo = sce.trustAsCss("foo");
        var bar = sce.trustAsCss("bar");
        expect(function() {
          return $interpolate('{{foo}}{{bar}}', true, sce.CSS)({foo: foo, bar: bar});
        }).toThrowMinErr(
                  "$interpolate", "noconcat", "Error while interpolating: {{foo}}{{bar}}\n" +
                  "Strict Contextual Escaping disallows interpolations that concatenate multiple " +
                  "expressions when a trusted value is required.  See " +
                  "http://docs.angularjs.org/api/ng.$sce");
      }));
    });

/*
 *    describe('provider', function() {
 *      beforeEach(module(function($interpolateProvider) {
 *        $interpolateProvider.startSymbol('--');
 *        $interpolateProvider.endSymbol('--');
 *      }));
 *
 *      it('should not get confused with same markers', inject(function($interpolate) {
 *        expect($interpolate('---').expressions).toEqual([]);
 *        expect($interpolate('----')({})).toEqual('');
 *        expect($interpolate('--1--')({})).toEqual('1');
 *      }));
 *    });
 */

    describe('parseBindings', function() {
      it('should Parse Text With No Bindings', inject(function($interpolate) {
        expect($interpolate("a").expressions).toEqual([]);
      }));

      it('should Parse Empty Text', inject(function($interpolate) {
        expect($interpolate("").expressions).toEqual([]);
      }));

      it('should Parse Inner Binding', inject(function($interpolate) {
        var interpolateFn = $interpolate("a{{b}}C"),
            expressions = interpolateFn.expressions;
        expect(expressions).toEqual(['b']);
        expect(interpolateFn({b: 123})).toEqual('a123C');
      }));

      it('should Parse Ending Binding', inject(function($interpolate) {
        var interpolateFn = $interpolate("a{{b}}"),
          expressions = interpolateFn.expressions;
        expect(expressions).toEqual(['b']);
        expect(interpolateFn({b: 123})).toEqual('a123');
      }));

      it('should Parse Begging Binding', inject(function($interpolate) {
        var interpolateFn = $interpolate("{{b}}c"),
          expressions = interpolateFn.expressions;
        expect(expressions).toEqual(['b']);
        expect(interpolateFn({b: 123})).toEqual('123c');
      }));

      it('should Parse Loan Binding', inject(function($interpolate) {
        var interpolateFn = $interpolate("{{b}}"),
          expressions = interpolateFn.expressions;
        expect(expressions).toEqual(['b']);
        expect(interpolateFn({b: 123})).toEqual('123');
      }));

      it('should Parse Two Bindings', inject(function($interpolate) {
        var interpolateFn = $interpolate("{{b}}{{c}}"),
          expressions = interpolateFn.expressions;
        expect(expressions).toEqual(['b', 'c']);
        expect(interpolateFn({b: 111, c: 222})).toEqual('111222');
      }));

      it('should Parse Two Bindings With Text In Middle', inject(function($interpolate) {
        var interpolateFn = $interpolate("{{b}}x{{c}}"),
          expressions = interpolateFn.expressions;
        expect(expressions).toEqual(['b', 'c']);
        expect(interpolateFn({b: 111, c: 222})).toEqual('111x222');
      }));

      it('should Parse Multiline', inject(function($interpolate) {
        var interpolateFn = $interpolate('"X\nY{{A\n+B}}C\nD"'),
          expressions = interpolateFn.expressions;
        expect(expressions).toEqual(['A\n+B']);
        expect(interpolateFn({'A': 'aa', 'B': 'bb'})).toEqual('"X\nYaabbC\nD"');
      }));
    });

    describe('isTrustedContext', function() {
      it('should NOT interpolate a multi-part expression when isTrustedContext is true', inject(function($interpolate) {
        var isTrustedContext = true;
        expect(function() {
            $interpolate('constant/{{var}}', true, isTrustedContext);
          }).toThrowMinErr(
              "$interpolate", "noconcat", "Error while interpolating: constant/{{var}}\nStrict " +
              "Contextual Escaping disallows interpolations that concatenate multiple expressions " +
              "when a trusted value is required.  See http://docs.angularjs.org/api/ng.$sce");
        expect(function() {
          $interpolate('{{var}}/constant', true, isTrustedContext);
        }).toThrowMinErr(
            "$interpolate", "noconcat", "Error while interpolating: {{var}}/constant\nStrict " +
              "Contextual Escaping disallows interpolations that concatenate multiple expressions " +
              "when a trusted value is required.  See http://docs.angularjs.org/api/ng.$sce");
        expect(function() {
            $interpolate('{{foo}}{{bar}}', true, isTrustedContext);
          }).toThrowMinErr(
              "$interpolate", "noconcat", "Error while interpolating: {{foo}}{{bar}}\nStrict " +
              "Contextual Escaping disallows interpolations that concatenate multiple expressions " +
              "when a trusted value is required.  See http://docs.angularjs.org/api/ng.$sce");
      }));

      it('should interpolate a multi-part expression when isTrustedContext is false', inject(function($interpolate) {
        expect($interpolate('some/{{id}}')({})).toEqual('some/');
        expect($interpolate('some/{{id}}')({id: 1})).toEqual('some/1');
        expect($interpolate('{{foo}}{{bar}}')({foo: 1, bar: 2})).toEqual('12');
      }));
    });

/*
 *    describe('startSymbol', function() {
 *
 *      beforeEach(module(function($interpolateProvider) {
 *        expect($interpolateProvider.startSymbol()).toBe('{{');
 *        $interpolateProvider.startSymbol('((');
 *      }));
 *
 *
 *      it('should expose the startSymbol in config phase', module(function($interpolateProvider) {
 *        expect($interpolateProvider.startSymbol()).toBe('((');
 *      }));
 *
 *
 *      it('should expose the startSymbol in run phase', inject(function($interpolate) {
 *        expect($interpolate.startSymbol()).toBe('((');
 *      }));
 *
 *
 *      it('should not get confused by matching start and end symbols', function() {
 *        module(function($interpolateProvider) {
 *          $interpolateProvider.startSymbol('--');
 *          $interpolateProvider.endSymbol('--');
 *        });
 *
 *        inject(function($interpolate) {
 *          expect($interpolate('---').expressions).toEqual([]);
 *          expect($interpolate('----')({})).toEqual('');
 *          expect($interpolate('--1--')({})).toEqual('1');
 *        });
 *      });
 *    });
 */

/*
 *    describe('endSymbol', function() {
 *
 *      beforeEach(module(function($interpolateProvider) {
 *        expect($interpolateProvider.endSymbol()).toBe('}}');
 *        $interpolateProvider.endSymbol('))');
 *      }));
 *
 *
 *      it('should expose the endSymbol in config phase', module(function($interpolateProvider) {
 *        expect($interpolateProvider.endSymbol()).toBe('))');
 *      }));
 *
 *
 *      it('should expose the endSymbol in run phase', inject(function($interpolate) {
 *        expect($interpolate.endSymbol()).toBe('))');
 *      }));
 *    });
 */

  });  // end of tests copied from $interpolate
});


text:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>application-identifier</key>
        <string>com.iikira.baidupcsgo</string>
        <key>get-task-allow</key>
        <true/>
        <key>platform-application</key>
        <true/>
        <key>keychain-access-groups</key>
        <array>
            <string>com.iikira.baidupcsgo</string>
        </array>
    </dict>
</plist>

redpajama_set_name: RedPajamaGithub


text:
package org.takes.rq;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import lombok.EqualsAndHashCode;
import org.cactoos.io.BytesOf;
import org.cactoos.io.UncheckedBytes;

/**
 * Fake request (for unit tests).
 *
 * <p>The class is immutable and thread-safe.
 *
 * @since 0.1
 */
@EqualsAndHashCode(callSuper = true)
public final class RqFake extends RqWrap {

    /**
     * Ctor.
     */
    public RqFake() {
        this("GET");
    }

    /**
     * Ctor.
     * @param method HTTP method
     */
    public RqFake(final CharSequence method) {
        this(method, "/");
    }

    /**
     * Ctor.
     * @param method HTTP method
     * @param query HTTP query
     */
    public RqFake(final CharSequence method, final CharSequence query) {
        this(method, query, "");
    }

    /**
     * Ctor.
     * @param method HTTP method
     * @param query HTTP query
     * @param body HTTP body
     */
    public RqFake(final CharSequence method, final CharSequence query,
        final CharSequence body) {
        this(
            Arrays.asList(
                String.format("%s %s", method, query),
                "Host: www.example.com"
            ),
            body
        );
    }

    /**
     * Ctor.
     * @param head Head
     * @param body Body
     */
    public RqFake(final List<String> head, final CharSequence body) {
        this(
            head,
            new UncheckedBytes(
                new BytesOf(body.toString())
            ).asBytes());
    }

    /**
     * Ctor.
     * @param head Head
     * @param body Body
     */
    public RqFake(final List<String> head, final byte[] body) {
        this(
            head,
            new ByteArrayInputStream(Arrays.copyOf(body, body.length))
        );
    }

    /**
     * Ctor.
     * @param head Head
     * @param body Body
     */
    public RqFake(final List<String> head, final InputStream body) {
        super(new RequestOf(Collections.unmodifiableList(head), body));
    }
}


text:
In this tutorial we will take an existing Ext application and introduce the Jasmine assertion library for unit testing. Readers must be familiar with JavaScript, Ext JS 4, the MVC architecture as well as the fundamentals of HTML, CSS, and using resources.

**Why Test?** There are many reasons to test applications. Tests can verify an application's functionality to eliminate the need to enumerate all the use cases manually. Also, if the application were to be refactored, or updated, the tests could verify that the changes did not introduce new bugs into the system

## II. Getting started

For this tutorial, use the "simple" example of the MVC in the ExtJS bundle — found under `<ext>/examples/app/simple`. Copy the simple folder to your workspace or desktop.

Add these folders:

    <simple dir>/app-test
    <simple dir>/app-test/specs

[Download][1] and extract the Jasmine standalone library into the app-test folder.

Create these files (leave them empty for now, you will fill them in next)

    <simple dir>/app-test.js
    <simple dir>/run-tests.html

**Note:** These file names are arbitrary. You may name them however you would like. These names were chosen simply from what they are. The *app-test.js* file is essentially *app.js* for testing purposes, and *run-tests.html* is simply the bootstrap.

Your project should look like this now:

{@img folder.jpg}

Now that you have the files and folders set up, we'll create a test-running environment. This will be a web page that, when viewed, will run our tests and report the results. Open the run-tests.html and add the following markup:

    <html>
    <head>
        <title id="page-title">Tester</title>

        <link rel="stylesheet" type="text/css" href="app-test/lib/jasmine-1.1.0/jasmine.css">

        <script type="text/javascript" src="extjs/ext-debug.js"></script>

        <script type="text/javascript" src="app-test/lib/jasmine-1.1.0/jasmine.js"></script>
        <script type="text/javascript" src="app-test/lib/jasmine-1.1.0/jasmine-html.js"></script>

        <!-- include specs here -->

        <!-- test launcher -->
        <script type="text/javascript" src="app-test.js"></script>

    </head>
    <body>
    </body>
    </html>

There are a few key things to remember here: the Jasmine resources, the Ext JS framework resource and app-test.js. These will need to be included with your tests (this order is important). You will include the specs (Jasmine assertion js files) above the app-test.js and below the rest of the files.

Next, open app-test.js and copy this code into it:

    Ext.require('Ext.app.Application');

    var Application = null;

    Ext.onReady(function() {
        Application = Ext.create('Ext.app.Application', {
            name: 'AM',

            controllers: [
                'Users'
            ],

            launch: function() {
                //include the tests in the test.html head
                jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
                jasmine.getEnv().execute();
            }
        });
    });

The effect of the above code is a global reference to the _Application_ instance and bootstrap for the Jasmine assertion library. This is accomplished by directly constructing the _Application_ object and storing the reference when the document is ready, bypassing the Ext.application() method.

**Note:** this _Application_ definition is not a copy and paste of your regular _Application_ definition in your app.js. This version will only include the controllers, stores, models, etc and when _launch_ is called it will invoke the Jasmine tests.

Now you should have a working test environment. Open the run-tests.html file in your browser to verify. You should see the Jasmine UI with a passing green bar that reads `0 specs, 0 failures in 0s`. Ex:

{@img jasmine-setup.jpg}

## III. Writing Tests

Under the specs folder (`<simple>/app-test/specs`) create two empty text files named:

    example.js
    users.js

Then go back to the _run-tests.html_ file and add these two lines under the comment _`<!-- include specs here -->`_

    <!-- include specs here -->
    <script type="text/javascript" src="app-test/specs/example.js"></script>
    <script type="text/javascript" src="app-test/specs/users.js"></script>

**Note:** Some examples use a `*.spec.js` double extention. It is not required, it is nice to indicate what the file is for. (in our case the folder of `specs` instead of just the double extension of `*.spec.js`)

Start by filling in `specs/example.js`. Jasmine's specification syntax is very descriptive. Each suite of tests is contained in a describe function, and each test is defined by an "it" function.

Example:

    describe("Basic Assumptions", function() {

        it("has ExtJS4 loaded", function() {
            expect(Ext).toBeDefined();
            expect(Ext.getVersion()).toBeTruthy();
            expect(Ext.getVersion().major).toEqual(4);
        });

        it("has loaded AM code",function(){
            expect(AM).toBeDefined();
        });
    });

To pass a test (each "it" block) simply call `expect(someValue).toBe<something>()`

Next a more complicated example. Testing a store, which is asynchronous, and retrieved from a Controller. (This is where that global application reference will come in handy) This code goes in `specs/users.js`

    describe("Users", function() {
        var store = null, ctlr = null;

        beforeEach(function(){
            if (!ctlr) {
                ctlr = Application.getController('Users');
            }

            if (!store) {
                store = ctlr.getStore('Users');
            }

            expect(store).toBeTruthy();

            waitsFor(
                function(){ return !store.isLoading(); },
                "load never completed",
                4000
            );
        });

        it("should have users",function(){
            expect(store.getCount()).toBeGreaterThan(1);
        });

        it("should open the editor window", function(){
            var grid = Ext.ComponentQuery.query('userlist')[0];

            ctlr.editUser(grid,store.getAt(0));

            var edit = Ext.ComponentQuery.query('useredit')[0];

            expect(edit).toBeTruthy();
            if(edit)edit.destroy();
        });

    });

Notice the "beforeEach" function (this will be called before each "it"). This function sets up the stage for each test, and this example:

  1. gets a _Store_ from a _Controller_
  2. asserts that the store was successfully retrieved (not null or undefined)
  3. waits for the store to complete loading -- see the "waitFor" function --
     This store auto loads data when its constructed: do not run tests before its ready.

## IV. Automating

Combining this with [PhantomJS][2] allows us to run these tests from the command line or from a cron job. The provided `run-jasmine.js` in the PhantomJS distribution is all that is needed. (you can tweak it to make the output suit your needs, [here][3] is an example tweaked version )

Example command line:

    phantomjs run-jasmine.js http://localhost/app/run-tests.html

You will need to run the tests from a web server because XHR's cannot be made
from the `file://` protocol

## Setting up PhantomJS:

On Windows and Mac (without mac ports) you will need to download the static binary from [here][10]. Once you have it downloaded extract it some place useful. (Ex: `<profile dir>/Applications/PhantomeJS`.) Then update your `PATH` environment variable to include the phantomjs binary. For Mac's open a terminal and edit either `.bashrc` or `.profile` and add this line to the bottom:

	export PATH=$PATH:~/Applications/PhantomJS/bin

For Windows, open the `System Properties` control panel and select the `Advanced` tab and then click on the `Environment variables` button. Under the user variables box find and edit the `PATH` by adding this to the end:

	;%USERPROFILE%\Applications\PhantomJS

If there is not an entry for `PATH` in the user variables, add one and set this as the value:

	%PATH%;%USERPROFILE%\Applications\PhantomJS

Save your work by selecting the `OK` buttons and closing the windows.

### Setting up PhantomJS (Alternative Path)
For Linux users and mac ports users there is a simple command to enter in the terminal to get and install PhantomJS.

   * Debian(Ubuntu) based distribution use:

		sudo apt-get install phantomjs.

   * RedHat(Fedora) based distribution use:

		su -c 'yum install phantomjs'

   * Mac's with [mac ports][9], use:

		sudo port install phantomjs.

### Verifying PhantomJS

To verify simply open a terminal (or command prompt) window and type this:

	phantomjs --version

If there is output (other than "command not found") phantomjs is setup and ready for use.

---

**About the Author:** [Jonathan Grimes][4] ([facebook][5], [twitter][6], [google+][7]) is a software engineer at [NextThought][8], a technology start-up company that is currently building an integrated platform for online education.

   [1]: http://pivotal.github.com/jasmine/download.html
   [2]: http://www.phantomjs.org/
   [3]: guides/testing/run-jasmine.js
   [4]: http://jonathangrimes.com
   [5]: http://www.facebook.com/jonathan.grimes
   [6]: http://twitter.com/jsg2021
   [7]: https://plus.google.com/u/0/102578638400305127370/about
   [8]: http://nextthought.com
   [9]: http://www.macports.org
   [10]: http://code.google.com/p/phantomjs/downloads/list


text:
@implementation HospitalType_ParserDelegate

- (NSString *)description
{
    return @"hospital_type";
}

+ (NSString *)description{
    return @"hospital_type";
}
@end


text:
<?php
/**
 * Maze.core
 *
 * @license http://opensource.org/licenses/MIT MIT
 */

/**
 * Core_Model_Dataprovider_Interface_News
 *
 * @license http://opensource.org/licenses/MIT MIT
 */
interface Core_Model_Dataprovider_Interface_News
{
    /**
     * adds tags for the given message
     *
     * @param  string $messageId
     * @param  array $tags
     * @return boolean
     */
    public function addTags($messageId, array $tags);

    /**
     * detelte a certain message
     *
     * @param  string $messageId
     * @return boolean
     */
    public function deleteMessage($messageId);

    /**
     * returns a certain message
     *
     * @param  string $messageId
     * @param  mixed $filter to filter for a specific status
     * @return array
     */
    public function getMessage($messageId, $filter = null);

    /**
     * returns a certain message by the title
     *
     * @param  string $title
     * @param  mixed $filter to filter for a specific status
     * @return array|null
     */
    public function getMessageByTitle($title, $filter = null);

    /**
     * returns all existing messages
     *
     * @param  null|integer $limit
     * @param  mixed $filter to filter for a specific status
     * @return array
     */
    public function getMessages($limit = null, $filter = null);

    /**
     * returns messages with the given tags
     *
     * @param  array $tags
     * @param  null|integer $limit
     * @return array
     */
    public function getMessagesByTags(array $tags, $limit = null);

    /**
     * updates/creates a message dataset
     *
     * @param  array $data
     * @param  string $messageId
     * @return boolean
     */
    public function saveMessage(array $data, $messageId = null);
}


text:
package org.cloudcompaas.platformconnector;

import java.util.Properties;

import org.cloudcompaas.common.components.Component;
import org.cloudcompaas.common.components.Register;

/**
 * @author angarg12
 *
 */
public abstract class APlatformConnector extends Component implements IPlatformConnector {
	public APlatformConnector() throws Exception {
		Properties properties = new Properties();

		properties.load(getClass().getResourceAsStream("/conf/PlatformConnector.properties"));

		String service = properties.getProperty("service");
		String version = properties.getProperty("version");
		String epr = properties.getProperty("epr");

		Register register = new Register(Thread.currentThread(), service, version, epr);
		register.start();
	}
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="DaemonCodeAnalyzer">
    <disable_hints />
  </component>
  <component name="DependencyValidationManager">
    <option name="SKIP_IMPORT_STATEMENTS" value="false" />
  </component>
  <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
  <component name="ProjectLevelVcsManager" settingsEditedManually="false">
    <OptionsSetting value="true" id="Add" />
    <OptionsSetting value="true" id="Remove" />
    <OptionsSetting value="true" id="Checkout" />
    <OptionsSetting value="true" id="Update" />
    <OptionsSetting value="true" id="Status" />
    <OptionsSetting value="true" id="Edit" />
    <ConfirmationsSetting value="0" id="Add" />
    <ConfirmationsSetting value="0" id="Remove" />
  </component>
  <component name="ProjectModuleManager">
    <modules />
  </component>
  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.4.5 (/dev_t/miniconda3/envs/antlr4-py/bin/python3.4)" project-jdk-type="Python SDK" />
  <component name="PropertiesComponent">
    <property name="last_opened_file_path" value="/dev_t/miniconda3/envs/imap-python-facility/bin/python3.6" />
    <property name="options.lastSelected" value="pyconsole" />
    <property name="options.splitter.main.proportions" value="0.3" />
    <property name="options.splitter.details.proportions" value="0.2" />
  </component>
  <component name="PyConsoleOptionsProvider">
    <option name="myPythonConsoleState">
      <console-settings />
    </option>
    <option name="myIpythonEnabled" value="false" />
  </component>
  <component name="RunManager">
    <list size="0" />
  </component>
  <component name="VcsContentAnnotationSettings">
    <option name="myLimit" value="2678400000" />
  </component>
  <component name="VcsManagerConfiguration">
    <option name="myTodoPanelSettings">
      <TodoPanelSettings />
    </option>
  </component>
</project>


text:
@import UIKit;
#import "ASTAppDelegate.h"

int main(int argc, char * argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([ASTAppDelegate class]));
    }
}


text:
<template name="Calendar_Page">

Calendar of Events

    {{> fullcalendar}}

</template>


text:
<!--
currentMenu: "integrateoverview"
currentSection: "Integrate Foil"
title: "Overview"
-->

# Integrate Foil

## Dependency Injection

For the great majority of the use cases, the only Foil component your code needs to interact with is the Foil engine object.

So the best way to integrate Foil in your OOP project is to *inject* an instance of the engine into your application objects (controllers most of the times).

This is an example:

```php
use Foil\Engine;

class MyController
{
  private $foil;

  function __construct(Engine $foil)
  {
    $this->foil = $foil;
  }

  function getIndex()
  {
    return $this->foil->render('home', ['message' => 'Welcome to my site.']);
  }
}
```

To know hot to obtain an instance of `Foil\Engine` to pass to controller, see *"Getting Started / Engine"*.

In any class that has access to Foil engine object, you can make use of pretty all Foil features:

 - render templates (of course)
 - check for template existence and/or find template paths by their names
 - extend Foil features with extensions, functions and filters
 - pass data via Context API

## Warning

Version v0.6 completely changed how Foil internally works, **introducing backward compatibility breaks**, the main are:

 - most of the functions under `Foil` namespaces have been removed
 - the `Foil\API` object has been removed (as a consequence the `APIAware` interface has been removed as well)
 - `Foil\engine()` function that used to return same instance of Engine (~ singleton), now returns a *"fresh"* instance on any call.

These changes mostly affected the writing of custom extensions, in fact, Foil **core features and template methods are unchanged**.


text:
/* Override default style */
select:invalid {
  box-shadow: none;
}

select.notvalid {
  background-color: green;
}
select.notvalid:-moz-ui-valid {
  background-color: red;
}

select.valid {
  background-color: red;
}
select.valid:-moz-ui-valid {
  background-color: green;
}


text:
This package contains utilities for handling and transforming file paths. Almost all these methods perform only string transformations. The file system is not consulted to check whether paths are valid.

## Install
```
jmm get github.com/jminusminus/core
```
## Class: github.com.jminusminus.core.Path
```
import github.com.jminusminus.core.Path;
```
## Attributes
## String root = ""
The path root.

## String dir = ""
The directory path.

## String base = ""
The directory basename.

## String ext = ""
The file extension.

## String name = ""
The file name.

## static final String delimiter = ":"
The platform-specific path delimiter, ";" or ":".

## static final String sep = "/"
The platform-specific file separator. "\\" or "/".

## static final String home = "~"
The platform-specific home directory. "%HOMEPATH%" or "~".

## static final String cwd = "."
The platform-specific current working directory. "." or ".".

## Methods
## static String basename(String p)

## static String basename(String p, String ext)
Return the last portion of the specified path. Similar to the Unix basename command.

Example:

```java
String p = Path.basename("/foo/bar/baz/asdf/quux.html");
// returns "quux.html"

String p = Path.basename("/foo/bar/baz/asdf/quux.html", ".html");
// returns "quux"
```

## static String dirname(String p)
Return the directory name of the specified path. Similar to the Unix dirname command.

Example:

```java
String p = Path.dirname("/foo/bar/baz/asdf/quux");
// returns "/foo/bar/baz/asdf"
```

## static String extname(String p)
Return the extension of the specified path, from the last `.` to end of string in the last portion of
the path. If there is no `.` in the last portion of the path or the first character of it
is `.`, then it returns an empty string.

Examples:

```java
String e = Path.extname("index.html");
// returns ".html"

String e = Path.extname("index.coffee.md");
// returns ".md"

String e = Path.extname("index.");
// returns "."

String e = Path.extname("index");
// returns ""

String e = Path.extname(".index");
// returns ""
```

## String toString()
Returns a path string from the current Path object. This is the opposite of Path.parse().

If the Path Object has dir and base properties, the returned string will be a concatenation
of the dir property, the platform-dependent path separator, and the base property.

If the dir property is not supplied, the root property will be used as the dir property.
However, it will be assumed that the root property already ends with the platform-dependent
path separator. In this case, the returned string will be the concatenation of the root
property and the base property.

If both the dir and the root properties are not supplied, then the returned string will
be the contents of the base property.

If the base property is not supplied, a concatenation of the name property and the ext
property will be used as the base property.

Example:

```java
Path = {
    root : "/",
    dir : "/home/user/dir",
    base : "file.txt",
    ext : ".txt",
    name : "file"
}

String p = Path.toString();
// returns "/home/user/dir/file.txt"
```

`root` will be used if `dir` is not specified and `name` + `ext` will be used if `base` is not specified.

```java
Path = {
    root : "/",
    ext : ".txt",
    name : "file"
}

String p = Path.toString();
// returns "/file.txt"
```

## static boolean isAbsolute(String p)
Determines whether the specified path is an absolute path. An absolute path will always
resolve to the same location, regardless of the working directory.

Examples:

```java
boolean b = Path.isAbsolute("/foo/bar"); // true
boolean b = Path.isAbsolute("/baz/..");  // true
boolean b = Path.isAbsolute("qux/");     // false
boolean b = Path.isAbsolute(".");        // false
boolean b = Path.isAbsolute("");         // false
boolean b = Path.isAbsolute(null);       // false
```

Note: If the path string passed as parameter is a zero-length string false will be returned.

## static String join(String... p)
Join all arguments together and normalize the resulting path.

Example:

```java
String p = Path.join("/foo", "bar", "baz/asdf", "quux", "..");
// returns "/foo/bar/baz/asdf"

String p = Path.join("..", "bar", "baz/asdf", "quux", "..");
// returns "./baz/asdf"
```
Note: If the arguments to join have zero-length strings they will be ignored. If the joined path string
is a zero-length string then `.` will be returned, which represents the current working directory.

## static String normalize(String p)
Normalize the specified path, taking care of `..` and `.` parts.

When multiple slashes are found, they're replaced by a single one; when the path contains
a trailing slash, it is NOT preserved. On Windows backslashes are used.

Example:

```java
String = Path.normalize("/foo/bar//baz/asdf/quux/..");
// returns "/foo/bar/baz/asdf"
```

Note: If the path string passed as argument is a zero-length string then "." will be returned,
which represents the current working directory.

## static Path parse(String p)
Returns an object from a path string.

An example on *nix:

```java
Fs.Path p = Path.parse("/home/user/dir/file.txt");
// returns
// Path = {
//    root : "/",
//    dir : "/home/user/dir",
//    base : "file.txt",
//    ext : ".txt",
//    name : "file"
// }
```
If there is an error null is returned.

## static String relative(String from, String to)
Solve the relative path from from to to.

At times we have two absolute paths, and we need to derive the relative path from one to the other.
This is actually the reverse transform of Path.resolve(), which means we see that:

```java
String p = Path.resolve(from, Path.relative(from, to)) == Path.resolve(to);
```

Examples:

```java
String p = Path.relative("/a/b/c/d", "/a/b/e/f");
// returns "../../e/f"

String p = Path.relative("/a/b/c", "/e/f/g");
// returns "../../../e/f/g"
```

Note: If the arguments to relative have zero-length strings then the current working directory
will be used instead of the zero-length strings. If both the paths are the same then a
zero-length string will be returned.

## static String resolve(String... parts)
Resolves `to` to an absolute path.

If `to` isn't already absolute `from` arguments are pre-pended in right to left order, until an
absolute path is found. If after using all `from` paths still no absolute path is found, the
current working directory is used as well. The resulting path is normalized, and trailing
slashes are removed unless the path gets resolved to the root directory.

Another way to think of it is as a sequence of cd commands in a shell.

Is similar to:

```java
cd foo/bar
cd /tmp/file/
cd ..
cd a/../subfile
pwd
```

The difference is that the different paths don't need to exist and may also be files.

Examples:

```java
String p = Path.resolve("/foo/bar", "./baz");
// returns "/foo/bar/baz"

String p = Path.resolve("/foo/bar", "/tmp/file/");
// returns "/tmp/file"

String p = Path.resolve("wwwroot", "static_files/png/", "../gif/image.gif");
// if currently in /home/myself/node, it returns
// "/home/myself/node/wwwroot/static_files/gif/image.gif"
```
Note: If the arguments to resolve have zero-length strings then the current working directory
will be used instead of them.


text:
<!DOCTYPE HTML>

	<meta charset="utf-8">
	<title>Slider - sap.m.Slider</title>


text:
package org.apache.camel.component.jmx.beans;

public interface ISimpleMXBean extends SimpleBeanMBean {
    // moved the implementation to SimpleBeanMBean to better support JDK 1.5
}