text:
"""
Test pylti/test_chalice.py module
"""
from __future__ import absolute_import
import unittest

import httpretty
import oauthlib.oauth1
import os

from six.moves.urllib.parse import urlencode

from pylti.common import LTIException
# from pylti.chalice import LTI
from pylti.tests.test_chalice_app import app_exception, app

from chalice.config import Config
from chalice.local import LocalGateway

TYPE_FORM = 'application/x-www-form-urlencoded'

class TestChalice(unittest.TestCase):
    """
    Consumers.
    """
    # pylint: disable=too-many-public-methods
    consumers = {
        "__consumer_key__": {"secret": "__lti_secret__"}
    }
    # Chalice implementation stores consumers in environment variables
    os.environ['CONSUMER_KEY_SECRET___consumer_key__'] = '__lti_secret__'

    # Valid XML response from LTI 1.0 consumer
    expected_response = """<?xml version="1.0" encoding="UTF-8"?>
<imsx_POXEnvelopeResponse xmlns = "http://www.imsglobal.org/services/ltiv1p1\
/xsd/imsoms_v1p0">
    <imsx_POXHeader>
        <imsx_POXResponseHeaderInfo>
            <imsx_version>V1.0</imsx_version>
            <imsx_messageIdentifier>edX_fix</imsx_messageIdentifier>
            <imsx_statusInfo>
                <imsx_codeMajor>success</imsx_codeMajor>
                <imsx_severity>status</imsx_severity>
                <imsx_description>Score for StarX/StarX_DEMO/201X_StarX:\
edge.edx.org-i4x-StarX-StarX_DEMO-lti-40559041895b4065b2818c23b9cd9da8\
:18b71d3c46cb4dbe66a7c950d88e78ec is now 0.0</imsx_description>
                <imsx_messageRefIdentifier>
                </imsx_messageRefIdentifier>
            </imsx_statusInfo>
        </imsx_POXResponseHeaderInfo>
    </imsx_POXHeader>
    <imsx_POXBody><replaceResultResponse/></imsx_POXBody>
</imsx_POXEnvelopeResponse>
        """

    def setUp(self):
        """
        Setting up app config.
        """
        # self.config = {}
        # self.config['TESTING'] = True
        # self.config['SERVER_NAME'] = 'localhost'
        # self.config['WTF_CSRF_ENABLED'] = False
        # self.config['SECRET_KEY'] = 'you-will-never-guess'
        # self.config['PYLTI_CONFIG'] = {'consumers': self.consumers}
        # self.config['PYLTI_URL_FIX'] = {
        #     "https://localhost:8000/": {
        #         "https://localhost:8000/": "https://localhost:8000/"
        #     }
        # }
        # self.app = app.test_client()
        self.localGateway = LocalGateway(app, Config())
        app_exception.reset()

    @staticmethod
    def generate_launch_request(consumers, url,
                                lit_outcome_service_url=None,
                                roles=u'Instructor',
                                add_params=None):
        """
        Generate valid basic-lti-launch-request request with options.
        :param consumers: consumer map
        :param url: URL to sign
        :param lit_outcome_service_url: LTI callback
        :param roles: LTI role
        :return: signed request
        """
        # pylint: disable=unused-argument, too-many-arguments
        params = {'resource_link_id': u'edge.edx.org-i4x-MITx-ODL_ENG-lti-'
                                      u'94173d3e79d145fd8ec2e83f15836ac8',
                  'user_id': u'008437924c9852377e8994829aaac7a1',
                  'lis_result_sourcedid': u'MITx/ODL_ENG/2014_T1:'
                                          u'edge.edx.org-i4x-MITx-ODL_ENG-lti-'
                                          u'94173d3e79d145fd8ec2e83f15836ac8:'
                                          u'008437924c9852377e8994829aaac7a1',
                  'context_id': u'MITx/ODL_ENG/2014_T1',
                  'lti_version': u'LTI-1p0',
                  'launch_presentation_return_url': u'',
                  'lis_outcome_service_url': (lit_outcome_service_url or
                                              u'https://example.edu/'
                                              u'courses/MITx/ODL_ENG/'
                                              u'2014_T1/xblock/i4x:;_;'
                                              u'_MITx;_ODL_ENG;_lti;'
                                              u'_94173d3e79d145fd8ec2e'
                                              u'83f15836ac8'
                                              u'/handler_noauth/'
                                              u'grade_handler'),
                  'lti_message_type': u'basic-lti-launch-request'}

        if roles is not None:
            params['roles'] = roles

        if add_params is not None:
            params.update(add_params)

        urlparams = urlencode(params)

        client = oauthlib.oauth1.Client('__consumer_key__',
                                        client_secret='__lti_secret__',
                                        signature_method=oauthlib.oauth1.
                                        SIGNATURE_HMAC,
                                        signature_type=oauthlib.oauth1.
                                        SIGNATURE_TYPE_QUERY)
        signature = client.sign("{}{}".format(url, urlparams))
        signed_url = signature[0]
        new_url = signed_url[len('https://localhost'):]
        return new_url

    @staticmethod
    def get_exception():
        """
        Returns exception raised by PyLTI.
        :return: exception
        """
        return app_exception.get()

    @staticmethod
    def has_exception():
        """
        Check if PyLTI raised exception.
        :return: is exception raised
        """
        return app_exception.get() is not None

    @staticmethod
    def get_exception_as_string():
        """
        Return text of the exception raised by LTI.
        :return: text
        """
        return "{}".format(TestChalice.get_exception())

    def request_callback(self, request, cburi, headers):
        # pylint: disable=unused-argument
        """
        Mock expected response.
        """
        return 200, headers, self.expected_response

    def test_access_to_oauth_resource_unknown_protection(self):
        """
        Invalid LTI request scope.
        """
        self.localGateway.handle_request(method='GET',
                                         path='/unknown_protection',
                                         headers={
                                            'host': 'localhost',
                                            'x-forwarded-proto': 'https'
                                         },
                                         body='')
        self.assertTrue(self.has_exception())
        self.assertIsInstance(self.get_exception(), LTIException)
        self.assertEqual(self.get_exception_as_string(),
                         'Unknown request type')

    def test_access_to_oauth_resource_without_authorization_any(self):
        """
        Accessing LTI without establishing session.
        """
        self.localGateway.handle_request(method='GET',
                                         path='/any',
                                         headers={
                                            'host': 'localhost',
                                            'x-forwarded-proto': 'https'
                                         },
                                         body='')
        self.assertTrue(self.has_exception())
        self.assertIsInstance(self.get_exception(), LTIException)
        self.assertEqual(self.get_exception_as_string(),
                         'The Request Type any is not supported because '
                         'Chalice does not support session state. Change '
                         'the Request Type to initial or omit it from the '
                         'declaration.')

    def test_access_to_oauth_resource_without_authorization_session(self):
        """
        Accessing LTI session scope before session established.
        """
        self.localGateway.handle_request(method='GET',
                                         path='/session',
                                         headers={
                                            'host': 'localhost',
                                            'x-forwarded-proto': 'https'
                                         },
                                         body='')
        self.assertTrue(self.has_exception())
        self.assertIsInstance(self.get_exception(), LTIException)
        self.assertEqual(self.get_exception_as_string(),
                         'The Request Type session is not supported because '
                         'Chalice does not support session state. Change '
                         'the Request Type to initial or omit it from the '
                         'declaration.')

    def test_access_to_oauth_resource_without_authorization_initial_get(self):
        """
        Accessing LTI without basic-lti-launch-request parameters as GET.
        """
        self.localGateway.handle_request(method='GET',
                                         path='/initial',
                                         headers={
                                            'host': 'localhost',
                                            'x-forwarded-proto': 'https'
                                         },
                                         body='')
        self.assertTrue(self.has_exception())
        self.assertIsInstance(self.get_exception(), LTIException)
        self.assertEqual(self.get_exception_as_string(),
                         'This page requires a valid oauth session or request')

    def test_access_without_authorization_post_form(self):
        """
        Accessing LTI without basic-lti-launch-request parameters as POST.
        """
        self.localGateway.handle_request(method='POST',
                                         path='/initial',
                                         headers={
                                            'host': 'localhost',
                                            'Content-Type': TYPE_FORM
                                         },
                                         body='')
        self.assertTrue(self.has_exception())
        self.assertIsInstance(self.get_exception(), LTIException)
        self.assertEqual(self.get_exception_as_string(),
                         'This page requires a valid oauth session or request')

    # DELETE: No sessions in Chalice
    # def test_access_to_oauth_resource_in_session(self):
    #     """
    #     Accessing LTI after session established.
    #     """
    #     self.app.get('/setup_session')
    #     self.app.get('/session')
    #     self.assertFalse(self.has_exception())

    # DELETE: No sessions in Chalice
    # def test_access_to_oauth_resource_in_session_with_close(self):
    #     """
    #     Accessing LTI after session closed.
    #     """
    #     self.app.get('/setup_session')
    #     self.app.get('/session')
    #     self.assertFalse(self.has_exception())
    #     self.app.get('/close_session')
    #     self.app.get('/session')
    #     self.assertTrue(self.has_exception())

    def test_access_to_oauth_resource_get(self):
        """
        Accessing oauth_resource.
        """
        consumers = self.consumers
        url = 'https://localhost/initial?'
        new_url = self.generate_launch_request(consumers, url)
        self.localGateway.handle_request(method='GET',
                                         path=new_url,
                                         headers={
                                            'host': 'localhost',
                                            'x-forwarded-proto': 'https'
                                         },
                                         body='')
        self.assertFalse(self.has_exception())

    def test_access_to_oauth_resource_post(self):
        """
        Accessing oauth_resource.
        """
        consumers = self.consumers
        url = 'https://localhost/initial?'
        new_url = self.generate_launch_request(consumers, url)
        (path, body) = new_url.split("?")
        self.localGateway.handle_request(method='POST',
                                         path=path,
                                         headers={
                                            'host': 'localhost',
                                            'x-forwarded-proto': 'https'
                                         },
                                         body=body)
        self.assertFalse(self.has_exception())

    def test_access_to_oauth_resource_name_passed(self):
        """
        Check that name is returned if passed via initial request.
        """
        # pylint: disable=maybe-no-member
        consumers = self.consumers
        url = 'https://localhost/name?'
        add_params = {u'lis_person_sourcedid': u'person'}
        new_url = self.generate_launch_request(
            consumers, url, add_params=add_params
        )
        ret = self.localGateway.handle_request(method='GET',
                                               path=new_url,
                                               headers={
                                                   'host': 'localhost',
                                                   'x-forwarded-proto': 'https'
                                               },
                                               body='')
        self.assertFalse(self.has_exception())
        self.assertEqual(ret['body'], u'person')

    def test_access_to_oauth_resource_email_passed(self):
        """
        Check that email is returned if passed via initial request.
        """
        # pylint: disable=maybe-no-member
        consumers = self.consumers
        url = 'https://localhost/name?'
        add_params = {u'lis_person_contact_email_primary': u'email@email.com'}
        new_url = self.generate_launch_request(
            consumers, url, add_params=add_params
        )
        ret = self.localGateway.handle_request(method='GET',
                                               path=new_url,
                                               headers={
                                                   'host': 'localhost',
                                                   'x-forwarded-proto': 'https'
                                               },
                                               body='')
        self.assertFalse(self.has_exception())
        self.assertEqual(ret['body'], u'email@email.com')

    def test_access_to_oauth_resource_name_and_email_passed(self):
        """
        Check that name is returned if both email and name passed.
        """
        # pylint: disable=maybe-no-member
        consumers = self.consumers
        url = 'https://localhost/name?'
        add_params = {u'lis_person_sourcedid': u'person',
                      u'lis_person_contact_email_primary': u'email@email.com'}
        new_url = self.generate_launch_request(
            consumers, url, add_params=add_params
        )
        ret = self.localGateway.handle_request(method='GET',
                                               path=new_url,
                                               headers={
                                                   'host': 'localhost',
                                                   'x-forwarded-proto': 'https'
                                               },
                                               body='')
        self.assertFalse(self.has_exception())
        self.assertEqual(ret['body'], u'person')

    def test_access_to_oauth_resource_staff_only_as_student(self):
        """
        Deny access if user not in role.
        """
        consumers = self.consumers
        url = 'https://localhost/initial_staff?'
        student_url = self.generate_launch_request(
            consumers, url, roles='Student'
        )
        self.localGateway.handle_request(method='GET',
                                         path=student_url,
                                         headers={
                                             'host': 'localhost',
                                             'x-forwarded-proto': 'https'
                                         },
                                         body='')
        self.assertTrue(self.has_exception())

        learner_url = self.generate_launch_request(
            consumers, url, roles='Learner'
        )
        self.localGateway.handle_request(method='GET',
                                         path=learner_url,
                                         headers={
                                             'host': 'localhost',
                                             'x-forwarded-proto': 'https'
                                         },
                                         body='')
        self.assertTrue(self.has_exception())

    def test_access_to_oauth_resource_staff_only_as_administrator(self):
        """
        Allow access if user in role.
        """
        consumers = self.consumers
        url = 'https://localhost/initial_staff?'
        new_url = self.generate_launch_request(
            consumers, url, roles='Administrator'
        )
        self.localGateway.handle_request(method='GET',
                                         path=new_url,
                                         headers={
                                             'host': 'localhost',
                                             'x-forwarded-proto': 'https'
                                         },
                                         body='')
        self.assertFalse(self.has_exception())

    def test_access_to_oauth_resource_staff_only_as_unknown_role(self):
        """
        Deny access if role not defined.
        """
        consumers = self.consumers
        url = 'https://localhost/initial_unknown?'
        admin_url = self.generate_launch_request(
            consumers, url, roles='Administrator'
        )
        self.localGateway.handle_request(method='GET',
                                         path=admin_url,
                                         headers={
                                             'host': 'localhost',
                                             'x-forwarded-proto': 'https'
                                         },
                                         body='')
        self.assertTrue(self.has_exception())

    def test_access_to_oauth_resource_student_as_student(self):
        """
        Verify that the various roles we consider as students are students.
        """
        consumers = self.consumers
        url = 'https://localhost/initial_student?'

        # Learner Role
        learner_url = self.generate_launch_request(
            consumers, url, roles='Learner'
        )
        self.localGateway.handle_request(method='GET',
                                         path=learner_url,
                                         headers={
                                             'host': 'localhost',
                                             'x-forwarded-proto': 'https'
                                         },
                                         body='')
        self.assertFalse(self.has_exception())

        student_url = self.generate_launch_request(
            consumers, url, roles='Student'
        )
        self.localGateway.handle_request(method='GET',
                                         path=student_url,
                                         headers={
                                             'host': 'localhost',
                                             'x-forwarded-proto': 'https'
                                         },
                                         body='')
        self.assertFalse(self.has_exception())

    def test_access_to_oauth_resource_student_as_staff(self):
        """Verify staff doesn't have access to student only."""
        consumers = self.consumers
        url = 'https://localhost/initial_student?'
        staff_url = self.generate_launch_request(
            consumers, url, roles='Staff'
        )
        self.localGateway.handle_request(method='GET',
                                         path=staff_url,
                                         headers={
                                             'host': 'localhost',
                                             'x-forwarded-proto': 'https'
                                         },
                                         body='')
        self.assertTrue(self.has_exception())

    def test_access_to_oauth_resource_student_as_unknown(self):
        """Verify unknown role doesn't have access to student only."""
        consumers = self.consumers
        url = 'https://localhost/initial_student?'
        unknown_url = self.generate_launch_request(
            consumers, url, roles='FooBar'
        )
        self.localGateway.handle_request(method='GET',
                                         path=unknown_url,
                                         headers={
                                             'host': 'localhost',
                                             'x-forwarded-proto': 'https'
                                         },
                                         body='')
        self.assertTrue(self.has_exception())

    # DELETE: Chalice does not support any. Otherwise this is a duplicate of
    # prior test test_access_to_oauth_resource
    # def test_access_to_oauth_resource_any(self):
    #     """
    #     Test access to LTI protected resources.
    #     """
    #     url = 'https://localhost/any?'
    #     new_url = self.generate_launch_request(self.consumers, url)
    #     self.localGateway.handle_request(method='GET',
    #                                         path=new_url,
    #                                         headers={
    #                                             'host': 'localhost'
    #                                         },
    #                                         body='')
    #     self.assertFalse(self.has_exception())

    # UPDATED: Changed this test to use inital endpoint as it was not covered
    def test_access_to_oauth_resource_initial_norole(self):
        """
        Test access to LTI protected resources.
        """
        url = 'https://localhost/initial?'
        new_url = self.generate_launch_request(self.consumers, url, roles=None)
        self.localGateway.handle_request(method='GET',
                                         path=new_url,
                                         headers={
                                             'host': 'localhost',
                                             'x-forwarded-proto': 'https'
                                         },
                                         body='')
        self.assertFalse(self.has_exception())

    # UPDATED: Changed this test to use inital endpoint as it was not covered
    def test_access_to_oauth_resource_any_nonstandard_role(self):
        """
        Test access to LTI protected resources.
        """
        url = 'https://localhost/initial?'
        new_url = self.generate_launch_request(self.consumers, url,
                                               roles=u'ThisIsNotAStandardRole')
        self.localGateway.handle_request(method='GET',
                                         path=new_url,
                                         headers={
                                            'host': 'localhost',
                                            'x-forwarded-proto': 'https'
                                         },
                                         body='')
        self.assertFalse(self.has_exception())

    def test_access_to_oauth_resource_invalid(self):
        """
        Deny access to LTI protected resources
        on man in the middle attack.
        """
        url = 'https://localhost/initial?'
        new_url = self.generate_launch_request(self.consumers, url)
        bad_url = "{}&FAIL=TRUE".format(new_url)
        self.localGateway.handle_request(method='GET',
                                         path=bad_url,
                                         headers={
                                            'host': 'localhost',
                                            'x-forwarded-proto': 'https'
                                         },
                                         body='')
        self.assertTrue(self.has_exception())
        self.assertIsInstance(self.get_exception(), LTIException)
        self.assertEqual(self.get_exception_as_string(),
                         'OAuth error: Please check your key and secret')

    # DELETE: Chalice does not support sessions
    # def test_access_to_oauth_resource_invalid_after_session_setup(self):
    #     """
    #     Remove browser session on man in the middle attach.
    #     """
    #     self.app.get('/setup_session')
    #     self.app.get('/session')
    #     self.assertFalse(self.has_exception())

    #     url = 'https://localhost/initial?'
    #     new_url = self.generate_launch_request(self.consumers, url)

    #     self.app.get("{}&FAIL=TRUE".format(new_url))
    #     self.assertTrue(self.has_exception())
    #     self.assertIsInstance(self.get_exception(), LTIException)
    #     self.assertEqual(self.get_exception_as_string(),
    #                      'OAuth error: Please check your key and secret')

    # UPDATE: Original established a session and then called post_grade
    # Chalice does nto support sessions so initiate and post in one call
    @httpretty.activate
    def test_access_to_oauth_resource_post_grade(self):
        """
        Check post_grade functionality.
        """
        # pylint: disable=maybe-no-member
        uri = (u'https://example.edu/courses/MITx/ODL_ENG/2014_T1/xblock/'
               u'i4x:;_;_MITx;_ODL_ENG;_lti;'
               u'_94173d3e79d145fd8ec2e83f15836ac8/handler_noauth'
               u'/grade_handler')

        httpretty.register_uri(httpretty.POST, uri, body=self.request_callback)

        consumers = self.consumers
        url = 'https://localhost/post_grade/1.0?'
        new_url = self.generate_launch_request(consumers, url)
        ret = self.localGateway.handle_request(method='GET',
                                               path=new_url,
                                               headers={
                                                  'host': 'localhost',
                                                  'x-forwarded-proto': 'https'
                                               },
                                               body='')
        self.assertFalse(self.has_exception())
        self.assertEqual(ret['body'], "grade=True")

        url = 'https://localhost/post_grade/2.0?'
        new_url = self.generate_launch_request(consumers, url)
        ret = self.localGateway.handle_request(method='GET',
                                               path=new_url,
                                               headers={
                                                  'host': 'localhost',
                                                  'x-forwarded-proto': 'https'
                                               },
                                               body='')
        self.assertFalse(self.has_exception())
        self.assertEqual(ret['body'], "grade=False")

    # UPDATE: Original established a session and then called post_grade
    # Chalice does nto support sessions so initiate and post in one call
    @httpretty.activate
    def test_access_to_oauth_resource_post_grade_fail(self):
        """
        Check post_grade functionality fails on invalid response.
        """
        # pylint: disable=maybe-no-member
        uri = (u'https://example.edu/courses/MITx/ODL_ENG/2014_T1/xblock/'
               u'i4x:;_;_MITx;_ODL_ENG;_lti;'
               u'_94173d3e79d145fd8ec2e83f15836ac8/handler_noauth'
               u'/grade_handler')

        def request_callback(request, cburi, headers):
            # pylint: disable=unused-argument
            """
            Mock error response callback.
            """
            return 200, headers, "wrong_response"

        httpretty.register_uri(httpretty.POST, uri, body=request_callback)

        consumers = self.consumers
        url = 'https://localhost/post_grade/1.0?'
        new_url = self.generate_launch_request(consumers, url)
        ret = self.localGateway.handle_request(method='GET',
                                               path=new_url,
                                               headers={
                                                  'host': 'localhost',
                                                  'x-forwarded-proto': 'https'
                                               },
                                               body='')
        self.assertTrue(self.has_exception())
        self.assertEqual(ret['body'], "error")

    # DELETED: Not implemented. Sounds like an EdX edge case
    # @httpretty.activate
    # def test_access_to_oauth_resource_post_grade_fix_url(self):
    #     """
    #     Make sure URL remap works for edX vagrant stack.
    #     """
    #     # pylint: disable=maybe-no-member
    #     uri = 'https://localhost:8000/dev_stack'

    #     httpretty.register_uri(httpretty.POST, uri,
    #                            body=self.request_callback)

    #     url = 'https://localhost/initial?'
    #     new_url = self.generate_launch_request(
    #         self.consumers, url, lit_outcome_service_url=uri
    #     )
    #     ret = self.app.get(new_url)
    #     self.assertFalse(self.has_exception())

    #     ret = self.app.get("/post_grade/1.0")
    #     self.assertFalse(self.has_exception())
    #     self.assertEqual(ret.data.decode('utf-8'), "grade=True")

    #     ret = self.app.get("/post_grade/2.0")
    #     self.assertFalse(self.has_exception())
    #     self.assertEqual(ret.data.decode('utf-8'), "grade=False")

    @httpretty.activate
    def test_access_to_oauth_resource_post_grade2(self):
        """
        Check post_grade edX LTI2 functionality.
        """
        uri = (u'https://example.edu/courses/MITx/ODL_ENG/2014_T1/xblock/'
               u'i4x:;_;_MITx;_ODL_ENG;_lti;'
               u'_94173d3e79d145fd8ec2e83f15836ac8/handler_noauth'
               u'/lti_2_0_result_rest_handler/user/'
               u'008437924c9852377e8994829aaac7a1')

        httpretty.register_uri(httpretty.PUT, uri, body=self.request_callback)

        consumers = self.consumers
        url = 'https://localhost/post_grade2/1.0?'
        new_url = self.generate_launch_request(consumers, url)
        ret = self.localGateway.handle_request(method='GET',
                                               path=new_url,
                                               headers={
                                                  'host': 'localhost',
                                                  'x-forwarded-proto': 'https'
                                               },
                                               body='')
        self.assertFalse(self.has_exception())
        self.assertEqual(ret['body'], "grade=True")

        url = 'https://localhost/post_grade2/2.0?'
        new_url = self.generate_launch_request(consumers, url)
        ret = self.localGateway.handle_request(method='GET',
                                               path=new_url,
                                               headers={
                                                  'host': 'localhost',
                                                  'x-forwarded-proto': 'https'
                                               },
                                               body='')
        self.assertFalse(self.has_exception())
        self.assertEqual(ret['body'], "grade=False")

    @httpretty.activate
    def test_access_to_oauth_resource_post_grade2_fail(self):
        """
        Check post_grade edX LTI2 functionality
        """
        uri = (u'https://example.edu/courses/MITx/ODL_ENG/2014_T1/xblock/'
               u'i4x:;_;_MITx;_ODL_ENG;_lti;'
               u'_94173d3e79d145fd8ec2e83f15836ac8/handler_noauth'
               u'/lti_2_0_result_rest_handler/user/'
               u'008437924c9852377e8994829aaac7a1')

        def request_callback(request, cburi, headers):
            # pylint: disable=unused-argument
            """
            Mock expected response.
            """
            return 400, headers, self.expected_response

        httpretty.register_uri(httpretty.PUT, uri, body=request_callback)

        consumers = self.consumers
        url = 'https://localhost/post_grade2/1.0?'
        new_url = self.generate_launch_request(consumers, url)
        ret = self.localGateway.handle_request(method='GET',
                                               path=new_url,
                                               headers={
                                                  'host': 'localhost',
                                                  'x-forwarded-proto': 'https'
                                               },
                                               body='')
        self.assertTrue(self.has_exception())
        self.assertEqual(ret['body'], "error")

    def test_default_decorator(self):
        """
        Verify default decorator works.
        """
        url = 'https://localhost/default_lti?'
        new_url = self.generate_launch_request(self.consumers, url)
        self.localGateway.handle_request(method='GET',
                                         path=new_url,
                                         headers={
                                            'host': 'localhost',
                                            'x-forwarded-proto': 'https'
                                         },
                                         body='')
        self.assertFalse(self.has_exception())

    def test_default_decorator_bad(self):
        """
        Verify error handling works.
        """
        # Validate we get our error page when there is a bad LTI
        # request
        # pylint: disable=maybe-no-member
        ret = self.localGateway.handle_request(method='GET',
                                               path='/default_lti',
                                               headers={
                                                  'host': 'localhost',
                                                  'x-forwarded-proto': 'https'
                                               },
                                               body='')
        print(ret)
        self.assertEqual(ret['statusCode'], 500)


text:
package mil.nga.giat.geowave.core.ingest;

import mil.nga.giat.geowave.core.index.ByteArrayId;
import mil.nga.giat.geowave.core.store.adapter.AdapterStore;
import mil.nga.giat.geowave.core.store.adapter.DataAdapter;
import mil.nga.giat.geowave.core.store.adapter.WritableDataAdapter;
import mil.nga.giat.geowave.datastore.accumulo.mapreduce.output.GeoWaveOutputKey;

import org.apache.log4j.Logger;

/**
 * This models any information that is necessary to ingest an entry into
 * GeoWave: the adapter and index you wish to use as well as the actual data
 *
 * @param <T>
 *            The java type for the actual data being ingested
 */
public class GeoWaveData<T>
{
	private final static Logger LOGGER = Logger.getLogger(GeoWaveData.class);
	private final ByteArrayId adapterId;
	private final ByteArrayId indexId;
	private final WritableDataAdapter<T> adapter;
	private final T data;

	public GeoWaveData(
			final ByteArrayId adapterId,
			final ByteArrayId indexId,
			final T data ) {
		this.adapterId = adapterId;
		this.indexId = indexId;
		this.data = data;

		// in this case the actual adapter is meant to be looked up using the ID
		this.adapter = null;
	}

	public GeoWaveData(
			final WritableDataAdapter<T> adapter,
			final ByteArrayId indexId,
			final T data ) {
		this.adapter = adapter;
		this.data = data;
		this.indexId = indexId;

		this.adapterId = adapter.getAdapterId();
	}

	public WritableDataAdapter<T> getAdapter(
			final AdapterStore adapterCache ) {
		if (adapter != null) {
			return adapter;
		}
		final DataAdapter<?> adapter = adapterCache.getAdapter(adapterId);
		if (adapter instanceof WritableDataAdapter) {
			return (WritableDataAdapter<T>) adapter;
		}
		LOGGER.warn("Adapter is not writable");
		return null;
	}

	public ByteArrayId getIndexId() {
		return indexId;
	}

	public GeoWaveOutputKey getKey() {
		return new GeoWaveOutputKey(
				adapterId,
				indexId);
	}

	public T getValue() {
		return data;
	}
}

redpajama_set_name: RedPajamaGithub


text:
// Code generated by client-gen. DO NOT EDIT.

package v1alpha1

import (
	"context"
	"time"

	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	types "k8s.io/apimachinery/pkg/types"
	watch "k8s.io/apimachinery/pkg/watch"
	rest "k8s.io/client-go/rest"
	v1alpha1 "knative.dev/eventing-gitlab/pkg/apis/sources/v1alpha1"
	scheme "knative.dev/eventing-gitlab/pkg/client/clientset/versioned/scheme"
)

// GitLabSourcesGetter has a method to return a GitLabSourceInterface.
// A group's client should implement this interface.
type GitLabSourcesGetter interface {
	GitLabSources(namespace string) GitLabSourceInterface
}

// GitLabSourceInterface has methods to work with GitLabSource resources.
type GitLabSourceInterface interface {
	Create(ctx context.Context, gitLabSource *v1alpha1.GitLabSource, opts v1.CreateOptions) (*v1alpha1.GitLabSource, error)
	Update(ctx context.Context, gitLabSource *v1alpha1.GitLabSource, opts v1.UpdateOptions) (*v1alpha1.GitLabSource, error)
	UpdateStatus(ctx context.Context, gitLabSource *v1alpha1.GitLabSource, opts v1.UpdateOptions) (*v1alpha1.GitLabSource, error)
	Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
	DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
	Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.GitLabSource, error)
	List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.GitLabSourceList, error)
	Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
	Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.GitLabSource, err error)
	GitLabSourceExpansion
}

// gitLabSources implements GitLabSourceInterface
type gitLabSources struct {
	client rest.Interface
	ns     string
}

// newGitLabSources returns a GitLabSources
func newGitLabSources(c *SourcesV1alpha1Client, namespace string) *gitLabSources {
	return &gitLabSources{
		client: c.RESTClient(),
		ns:     namespace,
	}
}

// Get takes name of the gitLabSource, and returns the corresponding gitLabSource object, and an error if there is any.
func (c *gitLabSources) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.GitLabSource, err error) {
	result = &v1alpha1.GitLabSource{}
	err = c.client.Get().
		Namespace(c.ns).
		Resource("gitlabsources").
		Name(name).
		VersionedParams(&options, scheme.ParameterCodec).
		Do(ctx).
		Into(result)
	return
}

// List takes label and field selectors, and returns the list of GitLabSources that match those selectors.
func (c *gitLabSources) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.GitLabSourceList, err error) {
	var timeout time.Duration
	if opts.TimeoutSeconds != nil {
		timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
	}
	result = &v1alpha1.GitLabSourceList{}
	err = c.client.Get().
		Namespace(c.ns).
		Resource("gitlabsources").
		VersionedParams(&opts, scheme.ParameterCodec).
		Timeout(timeout).
		Do(ctx).
		Into(result)
	return
}

// Watch returns a watch.Interface that watches the requested gitLabSources.
func (c *gitLabSources) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
	var timeout time.Duration
	if opts.TimeoutSeconds != nil {
		timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
	}
	opts.Watch = true
	return c.client.Get().
		Namespace(c.ns).
		Resource("gitlabsources").
		VersionedParams(&opts, scheme.ParameterCodec).
		Timeout(timeout).
		Watch(ctx)
}

// Create takes the representation of a gitLabSource and creates it.  Returns the server's representation of the gitLabSource, and an error, if there is any.
func (c *gitLabSources) Create(ctx context.Context, gitLabSource *v1alpha1.GitLabSource, opts v1.CreateOptions) (result *v1alpha1.GitLabSource, err error) {
	result = &v1alpha1.GitLabSource{}
	err = c.client.Post().
		Namespace(c.ns).
		Resource("gitlabsources").
		VersionedParams(&opts, scheme.ParameterCodec).
		Body(gitLabSource).
		Do(ctx).
		Into(result)
	return
}

// Update takes the representation of a gitLabSource and updates it. Returns the server's representation of the gitLabSource, and an error, if there is any.
func (c *gitLabSources) Update(ctx context.Context, gitLabSource *v1alpha1.GitLabSource, opts v1.UpdateOptions) (result *v1alpha1.GitLabSource, err error) {
	result = &v1alpha1.GitLabSource{}
	err = c.client.Put().
		Namespace(c.ns).
		Resource("gitlabsources").
		Name(gitLabSource.Name).
		VersionedParams(&opts, scheme.ParameterCodec).
		Body(gitLabSource).
		Do(ctx).
		Into(result)
	return
}

// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *gitLabSources) UpdateStatus(ctx context.Context, gitLabSource *v1alpha1.GitLabSource, opts v1.UpdateOptions) (result *v1alpha1.GitLabSource, err error) {
	result = &v1alpha1.GitLabSource{}
	err = c.client.Put().
		Namespace(c.ns).
		Resource("gitlabsources").
		Name(gitLabSource.Name).
		SubResource("status").
		VersionedParams(&opts, scheme.ParameterCodec).
		Body(gitLabSource).
		Do(ctx).
		Into(result)
	return
}

// Delete takes name of the gitLabSource and deletes it. Returns an error if one occurs.
func (c *gitLabSources) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
	return c.client.Delete().
		Namespace(c.ns).
		Resource("gitlabsources").
		Name(name).
		Body(&opts).
		Do(ctx).
		Error()
}

// DeleteCollection deletes a collection of objects.
func (c *gitLabSources) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
	var timeout time.Duration
	if listOpts.TimeoutSeconds != nil {
		timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
	}
	return c.client.Delete().
		Namespace(c.ns).
		Resource("gitlabsources").
		VersionedParams(&listOpts, scheme.ParameterCodec).
		Timeout(timeout).
		Body(&opts).
		Do(ctx).
		Error()
}

// Patch applies the patch and returns the patched gitLabSource.
func (c *gitLabSources) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.GitLabSource, err error) {
	result = &v1alpha1.GitLabSource{}
	err = c.client.Patch(pt).
		Namespace(c.ns).
		Resource("gitlabsources").
		Name(name).
		SubResource(subresources...).
		VersionedParams(&opts, scheme.ParameterCodec).
		Body(data).
		Do(ctx).
		Into(result)
	return
}


text:
FROM alpine:3.5
LABEL maintainer "Abiola Ibrahim <abiola89@gmail.com>"

LABEL caddy_version="0.10.3" architecture="amd64"

ARG plugins=http.ratelimit

RUN apk add --no-cache openssh-client git tar curl

RUN curl --silent --show-error --fail --location \
      --header "Accept: application/tar+gzip, application/x-gzip, application/octet-stream" -o - \
      "https://caddyserver.com/download/linux/amd64?plugins=${plugins}&license=personal" \
    | tar --no-same-owner -C /usr/bin/ -xz caddy \
 && chmod 0755 /usr/bin/caddy \
 && /usr/bin/caddy -version

EXPOSE 80 443 2015
VOLUME /root/.caddy
WORKDIR /srv

COPY Caddyfile /etc/Caddyfile

ENTRYPOINT ["/usr/bin/caddy"]
CMD ["--conf", "/etc/Caddyfile", "--log", "stdout"]


text:
package qub;

public class DisposableAction extends BasicDisposable
{
    private final Action0 action;

    private DisposableAction(Action0 action)
    {
        PreCondition.assertNotNull(action, "action");

        this.action = action;
    }

    public static DisposableAction create(Action0 action)
    {
        return new DisposableAction(action);
    }

    @Override
    public Result<Boolean> dispose()
    {
        return Result.create(() ->
        {
            final boolean result = super.dispose().await();
            if (result)
            {
                this.action.run();
            }
            return result;
        });
    }
}


text:
# Page titles on Wikipedia may include dots, so this constraint is needed.

Rails.application.routes.draw do
  get 'errors/file_not_found'
  get 'errors/unprocessable'
  get 'errors/login_error'
  get 'errors/internal_server_error'
  get 'errors/incorrect_passcode'

  # Sessions
  devise_for :users, controllers: { omniauth_callbacks: 'omniauth_callbacks' }
  devise_scope :user do
    # OmniAuth may fall back to :new_user_session when the OAuth flow fails.
    # So, we treat it as a login error.
    get 'sign_in', to: 'errors#login_error', as: :new_user_session

    get 'sign_out', to: 'users#signout', as: :destroy_user_session
    get 'sign_out_oauth', to: 'devise/sessions#destroy',
                          as: :true_destroy_user_session
  end

  #UserProfilesController
  controller :user_profiles do
    get 'users/:username' => 'user_profiles#show' , constraints: { username: /.*/ }
    get 'user_stats' => 'user_profiles#stats'
    get 'stats_graphs' => 'user_profiles#stats_graphs'
    post 'users/update/:username' => 'user_profiles#update'
  end

  # Users
  resources :users, only: [:index, :show], param: :username, constraints: { username: /.*/ } do
    collection do
      get 'revisions'
    end
  end

  resources :assignments do
    resources :assignment_suggestions
  end

  get 'mass_enrollment/:course_id'  => 'mass_enrollment#index',
      constraints: { course_id: /.*/ }
  post 'mass_enrollment/:course_id'  => 'mass_enrollment#add_users',
      constraints: { course_id: /.*/ }

  # Self-enrollment: joining a course by entering a passcode or visiting a url
  get 'courses/:course_id/enroll/(:passcode)' => 'self_enrollment#enroll_self',
      constraints: { course_id: /.*/ }

  # Courses
  controller :courses do
    get 'courses/new' => 'courses#new',
        constraints: { id: /.*/ } # repeat of resources

    get 'courses/*id/manual_update' => 'courses#manual_update',
        :as => :manual_update, constraints: { id: /.*/ }
    get 'courses/*id/notify_untrained' => 'courses#notify_untrained',
        :as => :notify_untrained, constraints: { id: /.*/ }
    get 'courses/*id/needs_update' =>  'courses#needs_update',
        :as => :needs_update, constraints: { id: /.*/ }
    get 'courses/*id/check' => 'courses#check',
        :as => :check, constraints: { id: /.*/ }
    match 'courses/*id/campaign' => 'courses#list',
          constraints: { id: /.*/ }, via: [:post, :delete]
    match 'courses/*id/tag' => 'courses#tag',
          constraints: { id: /.*/ }, via: [:post, :delete]
    match 'courses/*id/user' => 'users#enroll',
          constraints: { id: /.*/ }, via: [:post, :delete]

    get 'courses/:school/:titleterm(/:endpoint(/*any))' => 'courses#show',
        defaults: { endpoint: 'overview' }, :as => 'show',
        constraints: {
          school: /[^\/]*/,
          titleterm: /[^\/]*/
        }
    post 'clone_course/:id' => 'course_clone#clone'
    post 'courses/:id/update_syllabus' => 'courses#update_syllabus'
    delete 'courses/:id/delete_all_weeks' => 'courses#delete_all_weeks',
      constraints: {
        id: /.*/
      }
  end

  get 'lookups/campaign(.:format)' => 'lookups#campaign'
  get 'lookups/tag(.:format)' => 'lookups#tag'
  get 'lookups/article(.:format)' => 'lookups#article'

  # Timeline
  resources :courses, constraints: { id: /.*/ } do
    resources :weeks, only: [:index, :new, :create], constraints: { id: /.*/ }
    # get 'courses' => 'courses#index'
  end
  resources :weeks, only: [:index, :show, :edit, :update, :destroy]
  resources :blocks, only: [:show, :edit, :update, :destroy]
  resources :gradeables, collection: { update_multiple: :put }
  post 'courses/:course_id/timeline' => 'timeline#update_timeline',
       constraints: { course_id: /.*/ }
  post 'courses/:course_id/enable_timeline' => 'timeline#enable_timeline',
       constraints: { course_id: /.*/ }
  post 'courses/:course_id/disable_timeline' => 'timeline#disable_timeline',
       constraints: { course_id: /.*/ }

  get 'revisions' => 'revisions#index'

  get 'articles/article_data' => 'articles#article_data'
  get 'articles/details' => 'articles#details'

  resources :courses_users, only: [:index]
  resources :alerts, only: [:create] do
    member do
      get 'resolve'
      put 'resolve'
    end
  end

  put 'greeting' => 'greeting#greet_course_students'

  # Article Finder
  if Features.enable_article_finder?
    get 'article_finder(/*any)' => 'article_finder#index'
    post 'article_finder(/*any)' => 'article_finder#results'
  end

  # Reports and analytics
  get 'analytics(/*any)' => 'analytics#index'
  post 'analytics(/*any)' => 'analytics#results'
  get 'ungreeted' => 'analytics#ungreeted'
  get 'course_csv' => 'analytics#course_csv'
  get 'course_edits_csv' => 'analytics#course_edits_csv'
  get 'course_uploads_csv' => 'analytics#course_uploads_csv'
  get 'course_students_csv' => 'analytics#course_students_csv'
  get 'course_articles_csv' => 'analytics#course_articles_csv'

  # Campaigns
  resources :campaigns, param: :slug, except: :show do
    member do
      get 'overview'
      get 'programs'
      get 'articles'
      get 'users'
      get 'students'
      get 'instructors'
      get 'courses'
      get 'articles_csv'
      put 'add_organizer'
      put 'remove_organizer'
      put 'remove_course'
    end
  end
  get 'campaigns/:slug.json',
      controller: :campaigns,
      action: :show
  get 'campaigns/:slug', to: redirect('campaigns/%{slug}/programs')
  get 'campaigns/:slug/programs/:courses_query',
      controller: :campaigns,
      action: :programs,
      to: 'campaigns/%{slug}/programs?courses_query=%{courses_query}'

  # Recent Activity
  get 'recent-activity/plagiarism/report' => 'recent_activity#plagiarism_report'
  get 'recent-activity(/*any)' => 'recent_activity#index', as: :recent_activity

  # Revision analytics JSON API for React
  get 'revision_analytics/dyk_eligible',
      controller: 'revision_analytics',
      action: 'dyk_eligible'
  get 'revision_analytics/suspected_plagiarism',
      controller: 'revision_analytics',
      action: 'suspected_plagiarism'
  get 'revision_analytics/recent_edits',
      controller: 'revision_analytics',
      action: 'recent_edits'
  get 'revision_analytics/recent_uploads',
      controller: 'revision_analytics',
      action: 'recent_uploads'

  # Revision Feedback
  get '/revision_feedback' => 'revision_feedback#index'

  # Wizard
  get 'wizards' => 'wizard#wizard_index'
  get 'wizards/:wizard_id' => 'wizard#wizard'
  post 'courses/:course_id/wizard/:wizard_id' => 'wizard#submit_wizard',
       constraints: { course_id: /.*/ }

  # Training
  get 'training' => 'training#index'
  get 'training/:library_id' => 'training#show', as: :training_library
  get 'training/:library_id/:module_id' => 'training#training_module', as: :training_module
  post 'training_modules_users' => 'training_modules_users#create_or_update'
  get 'reload_trainings' => 'training#reload'

  get 'training_status' => 'training_status#show'

  # for React
  get 'training/:library_id/:module_id(/*any)' => 'training#slide_view'

  # API for slides for a module
  get 'training_modules' => 'training_modules#index'
  get 'training_module' => 'training_modules#show'

  # Misc
  # get 'courses' => 'courses#index'
  get 'explore' => 'explore#index'
  get 'unsubmitted_courses' => 'unsubmitted_courses#index'
  # get 'courses/*id' => 'courses#show', :as => :show, constraints: { id: /.*/ }

  # ask.wikiedu.org search box
  get 'ask' => 'ask#search'

  # Authenticated users root to the courses dashboard
  authenticated :user do
    root to: "dashboard#index", as: :courses_dashboard
  end

  # Unauthenticated users root to the home page
  root to: 'home#index'

  mount Rapidfire::Engine => "/surveys/rapidfire", :as => 'rapidfire'
  get '/surveys/results' => 'surveys#results_index', as: 'results'
  resources :survey_assignments, path: 'surveys/assignments'
  post '/survey_assignments/:id/send_test_email' => 'survey_assignments#send_test_email', as: 'send_test_email'
  post '/surveys/clone/:id' => 'surveys#clone'
  put '/surveys/question_position' => 'questions#update_position'
  get '/survey/results/:id' => 'surveys#results', as: 'survey_results'
  get '/survey/question/results/:id' => 'questions#results', as: 'question_results'
  get '/surveys/question_group_question/:id' => 'questions#get_question'
  get '/surveys/:id/question_group' => 'surveys#edit_question_groups', :as => "edit_question_groups"
  post '/surveys/question_group/clone/:id' => 'surveys#clone_question_group'
  post '/surveys/question/clone/:id' => 'surveys#clone_question'
  post '/surveys/update_question_group_position' => 'surveys#update_question_group_position'
  resources :surveys
  get '/surveys/:id/optout' => 'surveys#optout', as: 'optout'
  get '/surveys/select_course/:id' => 'surveys#course_select'
  put '/survey_notification' => 'survey_notifications#update'
  post '/survey_notification/create' => 'survey_assignments#create_notifications', as: 'create_notifications'
  post '/survey_notification/send' => 'survey_assignments#send_notifications', as: 'send_notifications'

  # Onboarding
  get 'onboarding(/*any)' => 'onboarding#index', as: :onboarding
  put 'onboarding/onboard' => 'onboarding#onboard', as: :onboard

  # Update Locale Preference
  post '/update_locale/:locale' => 'users#update_locale', as: :update_locale
  get '/update_locale/:locale' => 'users#update_locale'

  # Route aliases for React frontend
  get '/course_creator(/*any)' => 'dashboard#index', as: :course_creator

  get '/feedback' => 'feedback_form_responses#new', as: :feedback
  get '/feedback_form_responses' => 'feedback_form_responses#index'
  get '/feedback_form_responses/:id' => 'feedback_form_responses#show', as: :feedback_form_response
  post '/feedback_form_responses' => 'feedback_form_responses#create'
  get '/feedback/confirmation' => 'feedback_form_responses#confirmation'

  # Chat
  if Features.enable_chat?
    get '/chat/login' => 'chat#login'
    put '/chat/enable_for_course/:course_id' => 'chat#enable_for_course'
  end

  # Salesforce
  if Features.wiki_ed?
    put '/salesforce/link/:course_id' => 'salesforce#link'
    put '/salesforce/update/:course_id' => 'salesforce#update'
    get '/salesforce/create_media' => 'salesforce#create_media'
  end

  # Experiments
  namespace :experiments do
    get 'fall2017_cmu_experiment/:course_id/:email_code/opt_in' => 'fall2017_cmu_experiment#opt_in'
    get 'fall2017_cmu_experiment/:course_id/:email_code/opt_out' => 'fall2017_cmu_experiment#opt_out'
    get 'fall2017_cmu_experiment/course_list' => 'fall2017_cmu_experiment#course_list'
  end

  resources :admin
  resources :alerts_list

  require 'sidekiq/web'
  authenticate :user, lambda { |u| u.admin? } do
    mount Sidekiq::Web => '/sidekiq'
  end

  get '/styleguide' => 'styleguide#index'

  # Errors
  match '/404', to: 'errors#file_not_found', via: :all
  match '/422', to: 'errors#unprocessable', via: :all
  match '/599', to: 'errors#login_error', via: :all
  match '/500', to: 'errors#internal_server_error', via: :all
end


text:
// ----------------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------

using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Management.Automation;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.WindowsAzure.Commands.Common.Models;
using Microsoft.WindowsAzure.Commands.SqlDatabase.Database.Cmdlet;
using Microsoft.WindowsAzure.Commands.SqlDatabase.Properties;
using Microsoft.WindowsAzure.Commands.SqlDatabase.Services.Common;
using Microsoft.WindowsAzure.Commands.SqlDatabase.Services.Server;
using Microsoft.WindowsAzure.Commands.SqlDatabase.Test.UnitTests.MockServer;
using Microsoft.WindowsAzure.Commands.SqlDatabase.Test.Utilities;
using Microsoft.WindowsAzure.Commands.Test.Utilities.Common;

namespace Microsoft.WindowsAzure.Commands.SqlDatabase.Test.UnitTests.Database.Cmdlet
{
    [TestClass]
    public class NewAzureSqlDatabaseServerContextTests : TestBase
    {
        [TestCleanup]
        public void CleanupTest()
        {
            MockServerHelper.SaveDefaultSessionCollection();
        }

        [TestMethod]
        public void TestGetManageUrl()
        {
            NewAzureSqlDatabaseServerContext contextCmdlet = new NewAzureSqlDatabaseServerContext();

            // Make sure that server name to Manage Url conversion is working
            contextCmdlet.ServerName = "server0001";
            Assert.AreEqual(
                new Uri("https://server0001.database.windows.net"),
                UnitTestHelper.InvokePrivate(
                    contextCmdlet,
                    "GetManageUrl",
                    NewAzureSqlDatabaseServerContext.ServerNameWithSqlAuthParamSet));

            // Make sure that fully qualified server name name to Manage Url conversion is working
            contextCmdlet.FullyQualifiedServerName = "server0003.database.windows.net";
            Assert.AreEqual(
                new Uri("https://server0003.database.windows.net"),
                UnitTestHelper.InvokePrivate(
                    contextCmdlet,
                    "GetManageUrl",
                    NewAzureSqlDatabaseServerContext.FullyQualifiedServerNameWithSqlAuthParamSet));

            // Make sure that Manage Url to Manage Url conversion is working properly
            contextCmdlet.ManageUrl = new Uri("https://server0005.database.windows.net");
            Assert.AreEqual(
                new Uri("https://server0005.database.windows.net"),
                UnitTestHelper.InvokePrivate(
                    contextCmdlet,
                    "GetManageUrl",
                    NewAzureSqlDatabaseServerContext.ManageUrlWithSqlAuthParamSet));

            // Make sure that server name to Manage Url conversion is working
            contextCmdlet.ServerName = "server0001";
            Assert.AreEqual(
                new Uri("https://server0001.database.windows.net"),
                UnitTestHelper.InvokePrivate(
                    contextCmdlet,
                    "GetManageUrl",
                    NewAzureSqlDatabaseServerContext.ServerNameWithCertAuthParamSet));

            // Make sure that fully qualified server name name to Manage Url conversion is working
            contextCmdlet.FullyQualifiedServerName = "server0003.database.windows.net";
            Assert.AreEqual(
                new Uri("https://server0003.database.windows.net"),
                UnitTestHelper.InvokePrivate(
                    contextCmdlet,
                    "GetManageUrl",
                    NewAzureSqlDatabaseServerContext.FullyQualifiedServerNameWithCertAuthParamSet));

            try
            {
                UnitTestHelper.InvokePrivate(
                    contextCmdlet,
                    "GetManageUrl",
                    "InvalidParamterSet");
                Assert.Fail("GetManageUrl with invalid parameter set should not succeed.");
            }
            catch (InvalidOperationException ex)
            {
                Assert.AreEqual(Resources.UnknownParameterSet, ex.Message);
            }
        }

        [TestMethod]
        public void NewAzureSqlDatabaseServerContextWithSqlAuth()
        {
            // Create standard context with both ManageUrl and ServerName overridden
            using (System.Management.Automation.PowerShell powershell =
                System.Management.Automation.PowerShell.Create())
            {
                NewAzureSqlDatabaseServerContextTests.CreateServerContextSqlAuth(
                    powershell,
                    "$context");
            }

            // Create context with just ManageUrl and a derived servername
            HttpSession testSession = MockServerHelper.DefaultSessionCollection.GetSession(
                "UnitTests.NewAzureSqlDatabaseServerContextWithSqlAuthDerivedName");
            testSession.ServiceBaseUri = MockServerHelper.CommonServiceBaseUri;

            using (System.Management.Automation.PowerShell powershell =
                System.Management.Automation.PowerShell.Create())
            {
                UnitTestHelper.ImportAzureModule(powershell);
                UnitTestHelper.CreateTestCredential(powershell);

                // Tell the sql auth factory to create a v2 context (skip checking sql version using select query).
                //
                SqlAuthContextFactory.sqlVersion = SqlAuthContextFactory.SqlVersion.v2;
                using (AsyncExceptionManager exceptionManager = new AsyncExceptionManager())
                {
                    Collection<PSObject> serverContext;
                    using (new MockHttpServer(
                        exceptionManager,
                        MockHttpServer.DefaultServerPrefixUri,
                        testSession))
                    {
                        serverContext = powershell.InvokeBatchScript(
                            string.Format(
                                CultureInfo.InvariantCulture,
                                @"$context = New-AzureSqlDatabaseServerContext " +
                                @"-ManageUrl {0} " +
                                @"-Credential $credential",
                                MockHttpServer.DefaultServerPrefixUri.AbsoluteUri),
                            @"$context");
                    }

                    Assert.AreEqual(0, powershell.Streams.Error.Count, "Errors during run!");
                    powershell.Streams.ClearStreams();

                    PSObject contextPsObject = serverContext.Single();
                    Assert.IsTrue(
                        contextPsObject.BaseObject is ServerDataServiceSqlAuth,
                        "Expecting a ServerDataServiceSqlAuth object");
                }
            }
        }

        /// <summary>
        /// Create a new server context using certificate authentication
        /// </summary>
        [TestMethod]
        public void NewAzureSqlDatabaseServerContextWithCertAuth()
        {
            AzureSubscription subscription = UnitTestHelper.CreateUnitTestSubscription();

            NewAzureSqlDatabaseServerContext serverContext = new NewAzureSqlDatabaseServerContext();
            ServerDataServiceCertAuth service = serverContext.GetServerDataServiceByCertAuth(
                "testServer",
                subscription);

            Assert.IsNotNull(service, "The ServerDataServiceCertAuth object returned from "
                + "NewAzureSqlDatabaseServerContext.GetServerDataServiceByCertAuth is null");
        }

        [TestMethod]
        public void NewAzureSqlDatabaseServerContextWithSqlAuthNegativeCases()
        {
            HttpSession testSession = MockServerHelper.DefaultSessionCollection.GetSession(
                "UnitTests.NewAzureSqlDatabaseServerContextWithSqlAuthNegativeCases");

            using (System.Management.Automation.PowerShell powershell =
                System.Management.Automation.PowerShell.Create())
            {
                UnitTestHelper.ImportAzureModule(powershell);
                UnitTestHelper.CreateTestCredential(powershell);

                powershell.Runspace.SessionStateProxy.SetVariable(
                    "serverName",
                    SqlDatabaseTestSettings.Instance.ServerName);

                using (AsyncExceptionManager exceptionManager = new AsyncExceptionManager())
                {
                    // Tell the sql auth factory to create a v2 context (skip checking sql version using select query).
                    //
                    SqlAuthContextFactory.sqlVersion = SqlAuthContextFactory.SqlVersion.v2;

                    // Test warning when different $metadata is received.
                    Collection<PSObject> serverContext;
                    using (new MockHttpServer(
                        exceptionManager,
                        MockHttpServer.DefaultServerPrefixUri,
                        testSession))
                    {
                        serverContext = powershell.InvokeBatchScript(
                            string.Format(
                                CultureInfo.InvariantCulture,
                                @"$context = New-AzureSqlDatabaseServerContext " +
                                @"-ServerName $servername " +
                                @"-ManageUrl {0} " +
                                @"-Credential $credential",
                                MockHttpServer.DefaultServerPrefixUri.AbsoluteUri),
                            @"$context");
                    }

                    Assert.AreEqual(1, powershell.Streams.Error.Count, "Errors during run!");
                    Assert.AreEqual(2, powershell.Streams.Warning.Count, "Should have warning!");
                    powershell.Streams.ClearStreams();

                    // Tell the sql auth factory to create a v2 context (skip checking sql version using select query).
                    //
                    SqlAuthContextFactory.sqlVersion = SqlAuthContextFactory.SqlVersion.v2;

                    // Test error case
                    using (new MockHttpServer(
                        exceptionManager,
                        MockHttpServer.DefaultServerPrefixUri,
                        testSession))
                    {
                        powershell.InvokeBatchScript(
                            string.Format(
                                CultureInfo.InvariantCulture,
                                @"$context = New-AzureSqlDatabaseServerContext " +
                                @"-ServerName $servername " +
                                @"-ManageUrl {0} " +
                                @"-Credential $credential",
                                MockHttpServer.DefaultServerPrefixUri.AbsoluteUri),
                            @"$context");
                    }

                    Assert.AreEqual(1, powershell.Streams.Error.Count, "Should have errors!");
                    Assert.AreEqual(2, powershell.Streams.Warning.Count, "Should have warning!");
                    Assert.AreEqual(
                        "Test error message",
                        powershell.Streams.Error.First().Exception.Message);
                    Assert.IsTrue(
                        powershell.Streams.Warning.Any(
                            (w) => w.Message.StartsWith("Client Session Id:")),
                        "Client session Id not written to warning");
                    Assert.IsTrue(
                        powershell.Streams.Warning.Any(
                            (w) => w.Message.StartsWith("Client Request Id:")),
                        "Client request Id not written to warning");
                    powershell.Streams.ClearStreams();
                }
            }
        }

        /// <summary>
        /// Common helper method for other tests to create a context.
        /// </summary>
        /// <param name="contextVariable">The variable name that will hold the new context.</param>
        public static void CreateServerContextSqlAuth(
            System.Management.Automation.PowerShell powershell,
            string contextVariable)
        {
            HttpSession testSession = MockServerHelper.DefaultSessionCollection.GetSession(
                "UnitTest.Common.NewAzureSqlDatabaseServerContextWithSqlAuth");
            DatabaseTestHelper.SetDefaultTestSessionSettings(testSession);
            testSession.RequestValidator =
                new Action<HttpMessage, HttpMessage.Request>(
                (expected, actual) =>
                {
                    Assert.AreEqual(expected.RequestInfo.Method, actual.Method);
                    Assert.AreEqual(expected.RequestInfo.UserAgent, actual.UserAgent);
                    switch (expected.Index)
                    {
                        // Request 0-2: Create context with both ManageUrl and ServerName overriden
                        case 0:
                            // GetAccessToken call
                            DatabaseTestHelper.ValidateGetAccessTokenRequest(
                                expected.RequestInfo,
                                actual);
                            break;
                        case 1:
                            // Get server call
                            DatabaseTestHelper.ValidateHeadersForODataRequest(
                                expected.RequestInfo,
                                actual);
                            break;
                        case 2:
                            // $metadata call
                            Assert.IsTrue(
                                actual.RequestUri.AbsoluteUri.EndsWith("$metadata"),
                                "Incorrect Uri specified for $metadata");
                            DatabaseTestHelper.ValidateHeadersForServiceRequest(
                                expected.RequestInfo,
                                actual);
                            Assert.AreEqual(
                                expected.RequestInfo.Headers[DataServiceConstants.AccessTokenHeader],
                                actual.Headers[DataServiceConstants.AccessTokenHeader],
                                "AccessToken header does not match");
                            Assert.AreEqual(
                                expected.RequestInfo.Cookies[DataServiceConstants.AccessCookie],
                                actual.Cookies[DataServiceConstants.AccessCookie],
                                "AccessCookie does not match");
                            break;
                        default:
                            Assert.Fail("No more requests expected.");
                            break;
                    }
                });

            UnitTestHelper.ImportAzureModule(powershell);
            UnitTestHelper.CreateTestCredential(
                powershell,
                testSession.SessionProperties["Username"],
                testSession.SessionProperties["Password"]);

            // Tell the sql auth factory to create a v2 context (skip checking sql version using select query).
            //
            SqlAuthContextFactory.sqlVersion = SqlAuthContextFactory.SqlVersion.v2;

            Collection<PSObject> serverContext;
            using (AsyncExceptionManager exceptionManager = new AsyncExceptionManager())
            {
                using (new MockHttpServer(
                    exceptionManager,
                    MockHttpServer.DefaultServerPrefixUri,
                    testSession))
                {
                    serverContext = powershell.InvokeBatchScript(
                        string.Format(
                            CultureInfo.InvariantCulture,
                            @"{1} = New-AzureSqlDatabaseServerContext " +
                            @"-ServerName {2} " +
                            @"-ManageUrl {0} " +
                            @"-Credential $credential",
                            MockHttpServer.DefaultServerPrefixUri.AbsoluteUri,
                            contextVariable,
                            testSession.SessionProperties["Servername"]),
                        contextVariable);
                }
            }

            Assert.AreEqual(0, powershell.Streams.Error.Count, "Errors during run!");
            Assert.AreEqual(0, powershell.Streams.Warning.Count, "Warnings during run!");
            powershell.Streams.ClearStreams();

            PSObject contextPsObject = serverContext.Single();
            Assert.IsTrue(
                contextPsObject.BaseObject is ServerDataServiceSqlAuth,
                "Expecting a ServerDataServiceSqlAuth object");
        }

        /// <summary>
        /// Common helper method for other tests to create a context for ESA server.
        /// </summary>
        /// <param name="contextVariable">The variable name that will hold the new context.</param>
        public static void CreateServerContextSqlAuthV12(
            System.Management.Automation.PowerShell powershell,
            string manageUrl,
            string username,
            string password,
            string contextVariable)
        {
            UnitTestHelper.ImportAzureModule(powershell);
            UnitTestHelper.CreateTestCredential(
                powershell,
                username,
                password);

            // Tell the sql auth factory to create a v22 context (skip checking sql version using select query).
            //
            SqlAuthContextFactory.sqlVersion = SqlAuthContextFactory.SqlVersion.v12;

            Collection<PSObject> serverContext;
            using (AsyncExceptionManager exceptionManager = new AsyncExceptionManager())
            {
                serverContext = powershell.InvokeBatchScript(
                    string.Format(
                        CultureInfo.InvariantCulture,
                        @"{1} = New-AzureSqlDatabaseServerContext " +
                        @"-ManageUrl {0} " +
                        @"-Credential $credential ",
                        manageUrl,
                        contextVariable),
                    contextVariable);
            }

            Assert.AreEqual(0, powershell.Streams.Error.Count, "Errors during run!");
            Assert.AreEqual(0, powershell.Streams.Warning.Count, "Warnings during run!");
            powershell.Streams.ClearStreams();

            PSObject contextPsObject = serverContext.Single();
            Assert.IsTrue(
                contextPsObject.BaseObject is TSqlConnectionContext,
                "Expecting a TSqlConnectionContext object");
        }
    }
}


text:
/**
 * LoginRemoteService.java
 *
 * This file was auto-generated from WSDL
 * by the Apache Axis 1.4 Mar 02, 2009 (07:08:06 PST) WSDL2Java emitter.
 */

package com.google.api.ads.dfa.axis.v1_20;

public interface LoginRemoteService extends javax.xml.rpc.Service {
    public java.lang.String getloginAddress();

    public com.google.api.ads.dfa.axis.v1_20.LoginRemote getlogin() throws javax.xml.rpc.ServiceException;

    public com.google.api.ads.dfa.axis.v1_20.LoginRemote getlogin(java.net.URL portAddress) throws javax.xml.rpc.ServiceException;
}


text:
namespace blink {

std::unique_ptr<SkyView> SkyView::Create(SkyViewClient* client) {
  return std::unique_ptr<SkyView>(new SkyView(client));
}

SkyView::SkyView(SkyViewClient* client)
    : client_(client),
      weak_factory_(this) {
}

SkyView::~SkyView() {
}

void SkyView::SetDisplayMetrics(const SkyDisplayMetrics& metrics) {
  display_metrics_ = metrics;
  GetWindow()->UpdateWindowMetrics(display_metrics_);
}

void SkyView::CreateView(const String& name) {
  DCHECK(!dart_controller_);

  dart_controller_ = WTF::MakeUnique<DartController>();
  dart_controller_->CreateIsolateFor(WTF::MakeUnique<DOMDartState>(
      WTF::MakeUnique<Window>(this), name));

  DOMDartState* dart_state = dart_controller_->dart_state();
  DartState::Scope scope(dart_state);
  dart_state->window()->DidCreateIsolate();
  client_->DidCreateIsolate(dart_state->isolate());

  GetWindow()->UpdateWindowMetrics(display_metrics_);
}

void SkyView::RunFromLibrary(const WebString& name,
                             DartLibraryProvider* library_provider) {
  dart_controller_->RunFromLibrary(name, library_provider);
}

void SkyView::RunFromPrecompiledSnapshot() {
  dart_controller_->RunFromPrecompiledSnapshot();
}

void SkyView::RunFromSnapshot(const WebString& name,
                              mojo::ScopedDataPipeConsumerHandle snapshot) {
  dart_controller_->RunFromSnapshot(snapshot.Pass());
}

std::unique_ptr<sky::compositor::LayerTree> SkyView::BeginFrame(
    base::TimeTicks frame_time) {
  GetWindow()->BeginFrame(frame_time);
  return std::move(layer_tree_);
}

void SkyView::HandleInputEvent(const WebInputEvent& inputEvent) {
  TRACE_EVENT0("input", "SkyView::HandleInputEvent");

  RefPtr<Event> event;

  if (WebInputEvent::isPointerEventType(inputEvent.type)) {
    const WebPointerEvent& webEvent = static_cast<const WebPointerEvent&>(inputEvent);
    event = PointerEvent::create(webEvent);
  } else if (WebInputEvent::isKeyboardEventType(inputEvent.type)) {
    const WebKeyboardEvent& webEvent = static_cast<const WebKeyboardEvent&>(inputEvent);
    event = KeyboardEvent::create(webEvent);
  } else if (WebInputEvent::isWheelEventType(inputEvent.type)) {
    const WebWheelEvent& webEvent = static_cast<const WebWheelEvent&>(inputEvent);
    event = WheelEvent::create(webEvent);
  } else if (inputEvent.type == WebInputEvent::Back) {
    event = Event::create("back");
  }

  if (event)
    GetWindow()->DispatchEvent(event.get());
}

Window* SkyView::GetWindow() {
  return dart_controller_->dart_state()->window();
}

void SkyView::ScheduleFrame() {
  client_->ScheduleFrame();
}

void SkyView::Render(Scene* scene) {
  layer_tree_ = scene->takeLayerTree();
}

void SkyView::StartDartTracing() {
  dart_controller_->StartTracing();
}

void SkyView::StopDartTracing(mojo::ScopedDataPipeProducerHandle producer) {
  dart_controller_->StopTracing(producer.Pass());
}

} // namespace blink


text:
package game;

import game.controllers.ghosts.GhostsActions;
import game.controllers.ghosts.IGhostsController;
import game.controllers.ghosts.game.GameGhosts;
import game.controllers.pacman.HumanPacMan;
import game.controllers.pacman.IPacManController;
import game.controllers.pacman.PacManAction;
import game.core.G;
import game.core.Game;
import game.core.GameView;
import game.core.Replay;
import game.core._G_;

import java.awt.event.KeyListener;
import java.io.File;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * One simulator can run one instance of PacMan-vs-Ghosts game.
 *
 * Can be used for both head/less games.
 *
 * @author Jimmy
 */
public class PacManSimulator {

	public static class GameConfig {

		public int seed = -1;

		/**
		 * Whether POWER PILLS should be present within the environment.
		 */
		public boolean powerPillsEnabled = true;

		/**
		 * Total percentage of PILLS present within the level. If < 1, some (random) pills will be taken away.
		 */
		public double totalPills = 1;

		/**
		 * How many levels Ms PacMan may play (-1 => unbound).
		 */
		public int levelsToPlay = -1;

		public GameConfig clone() {
			GameConfig result = new GameConfig();

			result.seed = seed;
			result.powerPillsEnabled = powerPillsEnabled;
			result.totalPills = totalPills;
			result.levelsToPlay = levelsToPlay;

			return result;
		}

		public String asString() {
			return "" + seed + ";" + powerPillsEnabled + ";" + totalPills + ";" + levelsToPlay;
		}

		public void fromString(String line) {
			String[] all = line.split(";");
			seed = Integer.parseInt(all[0]);
			powerPillsEnabled = Boolean.parseBoolean(all[1]);
			totalPills = Double.parseDouble(all[2]);
			levelsToPlay = Integer.parseInt(all[3]);
		}

		public String getCSVHeader() {
			return "seed;powerPillsEnabled;totalPills;levelsToPlay";
		}

		public String getCSV() {
			return "" + seed + ";" + powerPillsEnabled + ";" + totalPills + ";" + levelsToPlay;
		}

	}

	private SimulatorConfig config;

	private GameView gv;

	private _G_ game;

    private long due;

    // REPLAY STUFF
    private StringBuilder replayData;
    private boolean replayFirstWrite;

	public synchronized Game run(final SimulatorConfig config) {
		System.out.println("[PacManSimulator] RUNNING: " + config.getOptions());

		// RESET INSTANCE & SAVE CONFIG
		reset(config);

		// INIT RANDOMNESS
		if (config.game.seed <= 0) {
			config.game.seed = new Random(System.currentTimeMillis()).nextInt();
			while (config.game.seed < 0) config.game.seed += Integer.MAX_VALUE;
		}
		G.rnd = new Random(config.game.seed);

		// INITIALIZE THE SIMULATION
		game = new _G_();
		game.newGame(config.game);

		// RESET CONTROLLERS
		config.pacManController.reset(game);
		if (config.ghostsController != null) config.ghostsController.reset(game);

		// INITIALIZE THE VIEW
		if (config.visualize) {
			gv = new GameView(game);
			if (config.visualizationScale2x) gv.setScale2x(true);
			gv.showGame();

			if (config.pacManController instanceof KeyListener) {
				gv.getFrame().addKeyListener((KeyListener)config.pacManController);
			}
			if (config.ghostsController != null && config.ghostsController instanceof KeyListener) {
				gv.getFrame().addKeyListener((KeyListener)config.ghostsController);
			}
		}

		// SETUP REPLAY RECORDING
		int lastLevel = game.getCurLevel();
		if (config.replay) {
			replayData = new StringBuilder();
			replayFirstWrite = true;
		}

		// START CONTROLLERS (threads auto-start during instantiation)
		ThinkingThread pacManThread =
			new ThinkingThread(
				"PAC-MAN",
				new IThinkingMethod() {
					@Override
					public void think() {
						PacManSimulator.this.config.pacManController.tick(game.copy(), due);
					}
				}
			);
		ThinkingThread ghostsThread =
			new ThinkingThread(
				"GHOSTS",
				new IThinkingMethod() {
					@Override
					public void think() {
						if (PacManSimulator.this.config.ghostsController != null) PacManSimulator.this.config.ghostsController.tick(game, due);
					}
				}
			);

		// START THE GAME
		try {
			while(!game.gameOver())
			{
				due = System.currentTimeMillis() + config.thinkTimeMillis;

				// WAKE UP THINKING THREADS
				thinkingLatch = new CountDownLatch(2);

				long start = System.currentTimeMillis();

				pacManThread.alert();
				ghostsThread.alert();

				// GIVE THINKING TIME
		        try{
		        	thinkingLatch.await(config.thinkTimeMillis, TimeUnit.MILLISECONDS);

		        	if (config.visualize) {
		        		if (System.currentTimeMillis() - start < config.thinkTimeMillis) {
		        			long sleepTime = config.thinkTimeMillis - (System.currentTimeMillis() - start);
		        			if (sleepTime > 4) {
		        				Thread.sleep(sleepTime);
		        			}
		        		}
		        	}
		        } catch(Exception e) {
		        }

		        if (pacManThread.thinking) {
		        	System.out.println("[SIMULATOR] PacMan is still thinking!");
		        }
		        if (ghostsThread.thinking) {
		        	System.out.println("[SIMULATOR] Ghosts are still thinking!");
		        }

		        thinkingLatch = null;

		        // OBTAIN ACTIONS
		        PacManAction  pacManAction  = config.pacManController.getAction().clone();
		        GhostsActions ghostsActions = (config.ghostsController == null ? null : config.ghostsController.getActions().clone());

		        // SIMULATION PAUSED?
		        boolean advanceGame = true;
		        if (config.mayBePaused) {
			        if (pacManAction.pauseSimulation || (ghostsActions != null && ghostsActions.pauseSimulation)) {
			        	if (!pacManAction.nextFrame && (ghostsActions == null || !ghostsActions.nextFrame)) {
			        		advanceGame = false;
			        	}
			        	config.pacManController.getAction().nextFrame = false;
			        	if (config.ghostsController != null) config.ghostsController.getActions().nextFrame = false;
			        }
		        }

		        // ADVANCE GAME
		        if (advanceGame) {
		        	int pacManLives = game.getLivesRemaining();

			        int replayStep[] = game.advanceGame(pacManAction, ghostsActions);

			        // SAVE ACTIONS TO REPLAY
			        if (config.replay) {
			        	// STORE ACTIONS
			        	storeActions(replayStep, game.getCurLevel()==lastLevel);
			        }

			        // NEW LEVEL?
			        if (game.getCurLevel() != lastLevel) {
			        	lastLevel=game.getCurLevel();

			        	// INFORM CONTROLLERS
			        	config.pacManController.nextLevel(game.copy());
			    		if (config.ghostsController != null) config.ghostsController.nextLevel(game.copy());

			    		// FLUSH REPLAY DATA TO FILE
			    		if (config.replay) {
			    			Replay.saveActions(config.game, (config.ghostsController == null ? 0 : config.ghostsController.getGhostCount()), replayData.toString(), config.replayFile, replayFirstWrite);
			        		replayFirstWrite = false;
			        		replayData = new StringBuilder();
			    		}
			        }

			        // PAC MAN KILLED?
			        if (pacManLives != game.getLivesRemaining()) {
			        	config.pacManController.killed();
			        }
		        }

		        // VISUALIZE GAME
		        if (config.visualize) {
		        	gv.repaint();
		        }
			}
		} finally {
			// KILL THREADS
			pacManThread.kill();
			ghostsThread.kill();

			// SAVE REPLAY DATA
			if (config.replay) {
				Replay.saveActions(config.game, (config.ghostsController == null ? 0 : config.ghostsController.getGhostCount()), replayData.toString(), config.replayFile, replayFirstWrite);
			}

			// CLEAN UP
			if (config.visualize) {
				if (config.pacManController instanceof KeyListener) {
					gv.getFrame().removeKeyListener((KeyListener)config.pacManController);
				}
				if (config.ghostsController instanceof KeyListener) {
					gv.getFrame().removeKeyListener((KeyListener)config.ghostsController);
				}

				gv.getFrame().setTitle("[FINISHED]");
				gv.repaint();
			}
		}

		return game;
	}

	private void reset(SimulatorConfig config) {
		this.config = config;

		gv = null;
		game = null;
	}

	private void storeActions(int[] replayStep, boolean newLine) {
		replayData.append( (game.getTotalTime()-1) + "\t" );

	    for (int i=0;i < replayStep.length; i++) {
	    	replayData.append(replayStep[i]+"\t");
	    }

	    if(newLine) {
	    	replayData.append("\n");
	    }
	}

	private interface IThinkingMethod {

		public void think();

	}

	private CountDownLatch thinkingLatch;

	private class ThinkingThread extends Thread
	{
		public boolean thinking = false;
	    private IThinkingMethod method;
	    private boolean alive;

	    public ThinkingThread(String name, IThinkingMethod method)
	    {
	    	super(name);
	        this.method = method;
	        alive=true;
	        start();
	    }

	    public synchronized  void kill()
	    {
	        alive=false;
	        notify();
	    }

	    public synchronized void alert()
	    {
	        notify();
	    }

	    public synchronized void run()
	    {
	    	 try {
	        	while(alive)
		        {
		        	try {
		        		synchronized(this)
		        		{
	        				wait(); // waked-up via alert()
		                }
		        	} catch(InterruptedException e)	{
		                e.printStackTrace();
		            }

		        	if (alive) {
		        		thinking = true;
		        		method.think();
		        		thinking = false;
		        		try {
		        			thinkingLatch.countDown();
		        		} catch (Exception e) {
		        			// thinkingLatch may be nullified...
		        		}
		        	}

		        }
	        } finally {
	        	alive = false;
	        }
	    }
	}

	/**
	 * Run simulation according to the configuration.
	 * @param config
	 * @return
	 */
	public static Game play(SimulatorConfig config) {
		PacManSimulator simulator = new PacManSimulator();
		return simulator.run(config);
	}

	/**
	 * Run simulation visualized with ghosts.
	 * @param pacMan
	 * @param ghosts
	 * @return
	 */
	public static Game play(IPacManController pacMan, IGhostsController ghosts) {
		SimulatorConfig config = new SimulatorConfig();

		config.pacManController = pacMan;
		config.ghostsController = ghosts;

		config.replay = true;
		config.replayFile = new File("./replay.log");

		return play(config);
	}

	/**
	 * Run simulation visualized w/o ghosts.
	 * @param pacMan
	 * @param ghosts
	 * @return
	 */
	public static Game play(IPacManController pacMan) {
		return play(pacMan, null);
	}

	/**
	 * Run simulation headless.
	 * @param pacMan
	 * @param ghosts
	 * @return
	 */
	public static Game simulate(IPacManController pacMan, IGhostsController ghosts) {
		SimulatorConfig config = new SimulatorConfig();

		config.visualize = false;

		config.pacManController = pacMan;
		config.ghostsController = ghosts;

		config.replay = true;
		config.replayFile = new File("./replay.log");

		return play(config);
	}

	public static void main(String[] args) {
		// PLAY WITHOUT GHOSTS
		//play(new HumanPacMan());

		// PLAY WITH 1 GHOST
		// play(new HumanPacMan(), new GameGhosts(1, false));

		// PLAY WITH 2 GHOSTS
		//play(new HumanPacMan(), new GameGhosts(2, false));

		// PLAY WITH 3 GHOSTS
		//play(new HumanPacMan(), new GameGhosts(3, false));

		// PLAY WITH 4 GHOSTS
		play(new HumanPacMan(), new GameGhosts(4, false));
	}

}