text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	  <meta name="author" content="Prasanna Balaprakash" />
    <meta name="description" content="Personal web page">
    <link rel="favicon" href="static/img/favicon.ico">

      <title>Team</title>

    <link rel="stylesheet" href="academicons/css/academicons.css" />

    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"
    integrity="sha256-MfvZlkHCEqatNoGiOXveE8FIwMzZg4W85qfrfIFBfYc= sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ=="
    crossorigin="anonymous">

    <link rel="stylesheet" type="text/css" href="static/css/main.css" />
	<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Source+Sans+Pro:200,400,200bold,400old" />
	<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" />
  <link rel="stylesheet" type="text/css" href="static/css/syntax.css" />

Home

Research

Group

Publications

Current group members

            Sandeep Madireddy, Assistant Computer Scientist, 2019--Present

            Probabilistic Machine Learning, Neuromorphic Computing

               Romit Maulik, Assistant Computational Scientist, 2021--Present

              Physics-informed Machine Learning, Computational Fluid Dynamics

              Tanwi Mallick, Postdoctoral Fellow, 2018--Present

              Spatiotemporal Machine Learning, Natural Language Processing

              Krishnan Ragavan, Postdoctoral Fellow, 2019--Present

              Meta Continual Learning, Deep Learning Theory

              Jaehoon Koo, Postdoctoral Fellow, 2020--Present

              Deep Learning for Image Processing, Autotuning for HPC

              Sami Khairy, Postdoctoral Fellow, 2021--Present

              Reinforcement Learning, Beyond 5G networks

              Adarsha Balaji, Postdoctoral Fellow, 2022--Present

              Neuromorphic computing, Hardware Software Co-desing

              Hongwei Jin, Postdoctoral Fellow, 2022--Present

              Graph neural networks, Mathematical Optimization

              Romain Egele, Research Aide, 2018--Present

              Automated Machine Learning, Scalable Deep Learnig

              Joceran Gouneau, Research Aide, 2021--Present

              Automated Machine Learning, Scalable Deep Learnig

Alumni

Grant Getzelman, Predoctoral Researcher, 2019--2021

 Scott Emmons  (DOE CSGF Fellow, 2021. From University of California, Berkeley)

 Alec Linot  (Givens Fellow, with Romit Maulik, 2021.  From University of Wisconsin Madison)

 Michael Mccabe  (Givens Fellow, 2021. From University of Colorado Boulder)

 Yixuan Sun  (Givens Fellow, with Tanwi Mallick, 2020, 2021.  From Perdue University)

 Felix Edward Perez  (EERE, HPC4Mfg Internship, with Romain Egele, 2021,  From UT Dallas)

 Edward Friesema  (EERE Robotics Internship Program, with Sami Khairy, 2021. From University of Nevada)

Sami Khairy (Givens Fellow, 2019 and 2020. From Illinois Institute of Technology)

Shengli Jiang (Givens Fellow, 2020. From University of Wisconsin-Madison)

Thomas Randall (Givens Fellow, 2020. From Clemson University)

Andres Rodriguez Rey (NSF MSGI Fellow, 2020. From University of California, Sand Diego)

Akhil Pandey Akella (ALCF Summer Student, 2020. From Northern Illinois University)

Peihong Jiang (NSF MSGI Fellow, 2019. From Brown University)

Tianchen (Eric) Zhao (Givens Fellow, 2018. From University of Michigan)

Nimish Awalgaonkar (Givens Fellow, 2018. From Purdue University)

Dipnil Chakraborty (NSF MSGI Fellow, 2018. From University of Texas at Dallas)

Dipendra Jha (Givens Fellow, 2018. From Northwestern University)

Akash Roy (Research Aid, 2018. From University of Texas at Dallas)

Andy Jin (Jeff Metcalf Undergraduate Fellow, 2018. From University of Chicago)

Tian Ma (Jeff Metcalf Undergraduate Fellow, 2018. From University of Chicago)

YiMing Yu (NSF MSGI Fellow, 2017. From New Jersy Institute of Technology)

Prateek Agarwal (Resident Associate, 2017. From Illinois Institute of Technology)

Amal Fethi (Resident Associate, 2017. From ENS Paris, France)

Juan Li (Resident Associate, 2016. From University of Chicago)

Amit Roy (Givens Associate, 2015. From University of Utah)

Arnamoy Bhattacharyya (Givens Associate, 2014. From ETH Zurich, Switzerland)

Postdoctoral and internship opportunities

        I am looking for researchers and students with expertise in artificial intelligence, machine/deep learning, applied mathematics, and/or high performance computing at various levels (postdocs, graduates, and undergraduates).

Immediate openings:

        We have an immediate opening for postdoc researcher in scientific machine learning (SciML) and explainable artificial intelligence (XAI). Apply here.

Postdoctoral Fellowships:

        Wilkinson Fellowship

        Margaret Butler Fellowship

        Maria Goeppert Mayer Fellowship

Graduate Fellowships:

        Givens Associates

        Cody Associates

        Department of Energy Office of Science Graduate Student Research (SCGSR) Program

        National Science Foundation Mathematical Sciences Graduate Internship (NSF-MSGI) Program

Undergraduate Fellowships:

        Department of Energy Science Undergraduate Laboratory Internship (SULI) Program

        Note: Deadlines vary and some require coordination with an Argonne sponsor. Therefore, contact me well in advance if you are interested.

© All rights reserved. Powered by Jekyll and
            sustain with ♥

redpajama_set_name: RedPajamaGithub


text:
using System;

namespace System.Runtime.CompilerServices
{
    /// <summary>
    /// Support for dynamic interface casting. Specifically implementing this interface on a type will allow the
    /// type to support interfaces (for the purposes of casting and interface dispatch) that do not appear in its
    /// interface map.
    /// </summary>
    public interface ICastable
    {
        // This is called if casting this object to the given interface type would otherwise fail. Casting
        // here means the IL isinst and castclass instructions in the case where they are given an interface
        // type as the target type.
        //
        // A return value of true indicates the cast is valid.
        //
        // If false is returned when this is called as part of a castclass then the usual InvalidCastException
        // will be thrown unless an alternate exception is assigned to the castError output parameter. This
        // parameter is ignored on successful casts or during the evaluation of an isinst (which returns null
        // rather than throwing on error).
        //
        // No exception should be thrown from this method (it will cause unpredictable effects, including the
        // possibility of an immediate failfast).
        //
        // The results of this call are not cached, so it is advisable to provide a performant implementation.
        //
        // The results of this call should be invariant for the same class, interface type pair. That is
        // because this is the only guard placed before an interface invocation at runtime. If a type decides
        // it no longer wants to implement a given interface it has no way to synchronize with callers that
        // have already cached this relationship and can invoke directly via the interface pointer.
        bool IsInstanceOfInterface(RuntimeTypeHandle interfaceType, out Exception castError);

        // This is called as part of the interface dispatch mechanism when the dispatcher logic cannot find
        // the given interface type in the interface map of this object.
        //
        // It allows the implementor to return an alternate class type which does implement the interface. The
        // interface lookup shall be performed again on this type (failure to find the interface this time
        // resulting in a fail fast) and the corresponding implemented method on that class called instead.
        //
        // Naturally, since the call is dispatched to a method on a class which does not match the type of the
        // this pointer, extreme care must be taken in the implementation of the interface methods of this
        // surrogate type.
        //
        // No exception should be thrown from this method (it will cause unpredictable effects, including the
        // possibility of an immediate failfast).
        //
        // There is no error path defined here. By construction all interface dispatches will already have
        // been verified via the castclass/isinst mechanism (and thus a call to IsInstanceOfInterface above)
        // so this method is expected to succeed in all cases. The contract for interface dispatch does not
        // include any errors from the infrastructure, of which this is a part.
        //
        // The results of this lookup are cached so computation of the result is not as perf-sensitive as
        // IsInstanceOfInterface.
        RuntimeTypeHandle GetImplType(RuntimeTypeHandle interfaceType);
    }
}


text:
cd ..
mvn eclipse:clean eclipse:eclipse  -DdownloadSources=true -Dmaven.test.skip=true -U
cd -


text:
package main

import (
	"fmt"
	"log"
	"net/http"
	"sync"
	"time"
)

func main() {

	// Launch a goroutine to run the web service.
	go func() {

		// Create a new mux for handling routes.
		m := http.NewServeMux()

		// Bind a handler to the root route that
		m.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) {
			log.Println(req.URL.Path)

			// Create some fake latency.
			time.Sleep(1 * time.Second)

			// Any attempt to brew coffee with a teapot should result
			// in the HTTP error code 418 I'm a teapot and the resulting
			// entity body MAY be short and stout.
			res.WriteHeader(http.StatusTeapot)
		})

		// Start the http server to handle the request.
		http.ListenAndServe(":4000", m)
	}()

	// Get the current time so we can time how long this request takes.
	start := time.Now()

	// Call the handler function 100 times.
	call(100, func(i int) {

		// Call into the running service we started above.
		res, err := http.Get(fmt.Sprintf("http://localhost:4000/%d", i))
		if err != nil {
			log.Fatal(err)
		}

		// We should get the Teapot status.
		if res.StatusCode != http.StatusTeapot {
			log.Fatal("Oops!")
		}
	})

	// Display how long the request took.
	fmt.Printf("\nduration: %s\n", time.Now().Sub(start))
}

// call executes the provided function count number
// of times concurrently.
func call(count int, f func(index int)) {
	var w sync.WaitGroup
	w.Add(count)

	for i := 0; i < count; i++ {
		go func(index int) {
			f(index)
			w.Done()
		}(i)
	}

	w.Wait()
}


text:
<?php

namespace frontend\controllers;

use common\models\SchoolMajor;
use DateTime;
use frontend\components\job\PublishToMajors;
use frontend\components\job\PublishToSchools;
use frontend\components\job\PublishToStudents;
use frontend\components\JobHelper;
use frontend\components\JobSessionHelper;
use frontend\components\UploadHandler;
use frontend\components\WordPHP;
use frontend\models\Employer;
use frontend\models\JobApplicant;
use frontend\models\JobInvitation;
use frontend\models\JobPosting;
use frontend\models\Province;
use frontend\models\School;

use frontend\models\Student;
use Yii;
use frontend\models\Job;
use frontend\models\JobSearch;
use frontend\components\Controller;
use yii\data\Pagination;
use yii\helpers\Json;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\web\User;

/**
 * JobController implements the CRUD actions for Job model.
 */
class PublishToSchoolsController extends Controller
{

    public function beforeAction($action)
    {
        $session = Yii::$app->session->get('createJob');

        if ($session['filterType'] == 'publishToSchools') {
            return true;
        }
    }

    /**
     * publish-to-schools
     * @return string
     */
    public function actionSelectMajor()
    {
        $session = Yii::$app->session->get('createJob');
        $data['session'] = $session;
        return $this->render('select-major', $data);
    }

    public function actionSelectSchools()
    {
        $request = Yii::$app->request;
        if (isset($_GET['schoolId'])) {
            JobSessionHelper::set('schoolIds', $request->get('schoolId'));
            return $this->redirect(['overview']);
        } else if ($request->post('allSchools')) {
            JobSessionHelper::set('schoolIds', $request->post('allSchools'));
            return $this->redirect(['overview']);
        }
    }

    public function actionOverview()
    {
        $session = Yii::$app->session->get('createJob');
        $schools = School::find()->where(['IN', 'school_id', explode(',', $session['schoolIds'])])->all();
        $data['schools'] = $schools;
        return $this->render('overview', $data);
    }

    /**
     * publish-to-schools
     * @return string
     */
    public function actionAjaxGetSchools()
    {
        $request = Yii::$app->request;

        if ($request->isAjax) {
            return (new PublishToSchools())->ajaxGetSchools($request);
        }
    }

    //this is to test the tree view plugin, select multiple major ids to pull out schools
    public function actionGetSchoolByMajorId()
    {
        $schoolMajor = SchoolMajor::find()->where(['major_id'=>2116])->all();

//
//        $view = Yii::$app->view->render('@app/views/publish-to-schools/_school', [ 'schoolMajor' => $schoolMajor]);
//        return Json::encode($view);

        return $this->render('get-school-by-major-id', (['schoolMajor'=>$schoolMajor]));
    }

    //this is to test the tree view plugin, select multiple major ids to pull out schools
    public function actionAbout()
    {
      //  $schoolMajor = SchoolMajor::find()->where(['major_id'=>2116])->all();

     $request = Yii::$app->request;

        if ($request->isAjax) {
            return (new PublishToSchools())->about($request);
        }
    }
}


text:
package com.google.gapid.perfetto.views;

import static com.google.gapid.perfetto.TimeSpan.timeToString;
import static com.google.gapid.widgets.Widgets.createTableColumn;
import static com.google.gapid.widgets.Widgets.createTableViewer;
import static com.google.gapid.widgets.Widgets.packColumns;

import com.google.gapid.perfetto.models.CounterTrack;

import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;

public class CountersSelectionView extends Composite {
  public CountersSelectionView(Composite parent, State state, CounterTrack.Values sel) {
    super(parent, SWT.None);
    setLayout(new FillLayout());

    TableViewer viewer = createTableViewer(this, SWT.NONE);
    viewer.setContentProvider(new ArrayContentProvider());
    viewer.setLabelProvider(new LabelProvider());

    createTableColumn(
        viewer, "Time", r -> timeToString(sel.ts[(Integer)r] - state.getTraceTime().start));
    for (String name : sel.values.keySet()) {
      createTableColumn(viewer, name, r -> {
        if (sel.ids.get(name)[(Integer)r] == -1) {
          return "/";
        }
        return String.valueOf(sel.values.get(name)[(Integer)r]);
      });
    }

    // Skip the last row (it represents the end of the selection range).
    Integer[] rows = new Integer[sel.ts.length - 1];
    for (int i = 0; i < rows.length; i++) {
      rows[i] = i;
    }
    viewer.setInput(rows);
    packColumns(viewer.getTable());
  }
}


text:
#include "config.h"
#include "JSDOMWindowCustom.h"

#include "Frame.h"
#include "HTMLCollection.h"
#include "HTMLDocument.h"
#include "JSEvent.h"
#include "JSEventListener.h"
#include "JSHTMLAudioElement.h"
#include "JSHTMLCollection.h"
#include "JSHTMLOptionElement.h"
#include "JSImageConstructor.h"
#include "JSMessagePortCustom.h"
#include "JSWorker.h"
#include "Location.h"
#include "ScheduledAction.h"
#include "Settings.h"
#include "SharedWorkerRepository.h"

#if ENABLE(SHARED_WORKERS)
#include "JSSharedWorker.h"
#endif

#if ENABLE(IOS_TOUCH_EVENTS)
#include "JSTouchConstructorIOS.h"
#include "JSTouchListConstructorIOS.h"
#endif

#if ENABLE(WEB_AUDIO)
#include "JSAudioContext.h"
#endif

#if ENABLE(WEB_SOCKETS)
#include "JSWebSocket.h"
#endif

#if ENABLE(USER_MESSAGE_HANDLERS)
#include "JSWebKitNamespace.h"
#endif

using namespace JSC;

namespace WebCore {

void JSDOMWindow::visitAdditionalChildren(SlotVisitor& visitor)
{
    if (Frame* frame = impl().frame())
        visitor.addOpaqueRoot(frame);
}

static EncodedJSValue childFrameGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)
{
    return JSValue::encode(toJS(exec, jsCast<JSDOMWindow*>(slotBase)->impl().frame()->tree().scopedChild(propertyNameToAtomicString(propertyName))->document()->domWindow()));
}

static EncodedJSValue namedItemGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)
{
    JSDOMWindowBase* thisObj = jsCast<JSDOMWindow*>(slotBase);
    Document* document = thisObj->impl().frame()->document();

    ASSERT(BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObj->impl()));
    ASSERT(document);
    ASSERT(document->isHTMLDocument());

    AtomicStringImpl* atomicPropertyName = findAtomicString(propertyName);
    if (!atomicPropertyName || !toHTMLDocument(document)->hasWindowNamedItem(*atomicPropertyName))
        return JSValue::encode(jsUndefined());

    if (UNLIKELY(toHTMLDocument(document)->windowNamedItemContainsMultipleElements(*atomicPropertyName))) {
        RefPtr<HTMLCollection> collection = document->windowNamedItems(atomicPropertyName);
        ASSERT(collection->length() > 1);
        return JSValue::encode(toJS(exec, thisObj->globalObject(), WTF::getPtr(collection)));
    }

    return JSValue::encode(toJS(exec, thisObj->globalObject(), toHTMLDocument(document)->windowNamedItem(*atomicPropertyName)));
}

#if ENABLE(USER_MESSAGE_HANDLERS)
static EncodedJSValue jsDOMWindowWebKit(ExecState* exec, JSObject*, EncodedJSValue thisValue, PropertyName)
{
    JSDOMWindow* castedThis = toJSDOMWindow(JSValue::decode(thisValue));
    if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, castedThis->impl()))
        return JSValue::encode(jsUndefined());
    return JSValue::encode(toJS(exec, castedThis->globalObject(), castedThis->impl().webkitNamespace()));
}
#endif

bool JSDOMWindow::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
    JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(object);
    // When accessing a Window cross-domain, functions are always the native built-in ones, and they
    // are not affected by properties changed on the Window or anything in its prototype chain.
    // This is consistent with the behavior of Firefox.

    // We don't want any properties other than "close" and "closed" on a frameless window (i.e. one whose page got closed,
    // or whose iframe got removed).
    // FIXME: This doesn't fully match Firefox, which allows at least toString in addition to those.
    if (!thisObject->impl().frame()) {
        // The following code is safe for cross-domain and same domain use.
        // It ignores any custom properties that might be set on the DOMWindow (including a custom prototype).
        if (propertyName == exec->propertyNames().closed) {
            slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, jsDOMWindowClosed);
            return true;
        }
        if (propertyName == exec->propertyNames().close) {
            slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>);
            return true;
        }

        // FIXME: We should have a message here that explains why the property access/function call was
        // not allowed.
        slot.setUndefined();
        return true;
    } else
        slot.setWatchpointSet(thisObject->m_windowCloseWatchpoints);

    // We need to check for cross-domain access here without printing the generic warning message
    // because we always allow access to some function, just different ones depending whether access
    // is allowed.
    String errorMessage;
    bool allowsAccess = shouldAllowAccessToDOMWindow(exec, thisObject->impl(), errorMessage);

    // Look for overrides before looking at any of our own properties, but ignore overrides completely
    // if this is cross-domain access.
    if (allowsAccess && JSGlobalObject::getOwnPropertySlot(thisObject, exec, propertyName, slot))
        return true;

    // We need this code here because otherwise JSDOMWindowBase will stop the search before we even get to the
    // prototype due to the blanket same origin (shouldAllowAccessToDOMWindow) check at the end of getOwnPropertySlot.
    // Also, it's important to get the implementation straight out of the DOMWindow prototype regardless of
    // what prototype is actually set on this object.
    if (propertyName == exec->propertyNames().blur) {
        if (!allowsAccess) {
            slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionBlur, 0>);
            return true;
        }
    } else if (propertyName == exec->propertyNames().close) {
        if (!allowsAccess) {
            slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>);
            return true;
        }
    } else if (propertyName == exec->propertyNames().focus) {
        if (!allowsAccess) {
            slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionFocus, 0>);
            return true;
        }
    } else if (propertyName == exec->propertyNames().postMessage) {
        if (!allowsAccess) {
            slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionPostMessage, 2>);
            return true;
        }
    } else if (propertyName == exec->propertyNames().showModalDialog) {
        if (!DOMWindow::canShowModalDialog(thisObject->impl().frame())) {
            slot.setUndefined();
            return true;
        }
    } else if (propertyName == exec->propertyNames().toString) {
        // Allow access to toString() cross-domain, but always Object.prototype.toString.
        if (!allowsAccess) {
            slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, objectToStringFunctionGetter);
            return true;
        }
    }

    const HashTableValue* entry = JSDOMWindow::info()->propHashTable(exec)->entry(exec, propertyName);
    if (entry) {
        slot.setCacheableCustom(thisObject, allowsAccess ? entry->attributes() : ReadOnly | DontDelete | DontEnum, entry->propertyGetter());
        return true;
    }

#if ENABLE(USER_MESSAGE_HANDLERS)
    if (propertyName == exec->propertyNames().webkit && thisObject->impl().shouldHaveWebKitNamespaceForWorld(thisObject->world())) {
        slot.setCacheableCustom(thisObject, allowsAccess ? DontDelete | ReadOnly : ReadOnly | DontDelete | DontEnum, jsDOMWindowWebKit);
        return true;
    }
#endif

    // Do prototype lookup early so that functions and attributes in the prototype can have
    // precedence over the index and name getters.
    JSValue proto = thisObject->prototype();
    if (proto.isObject()) {
        if (asObject(proto)->getPropertySlot(exec, propertyName, slot)) {
            if (!allowsAccess) {
                thisObject->printErrorMessage(errorMessage);
                slot.setUndefined();
            }
            return true;
        }
    }

    // After this point it is no longer valid to cache any results because of
    // the impure nature of the property accesses which follow. We can move this
    // statement further down when we add ways to mitigate these impurities with,
    // for example, watchpoints.
    slot.disableCaching();

    // Check for child frames by name before built-in properties to
    // match Mozilla. This does not match IE, but some sites end up
    // naming frames things that conflict with window properties that
    // are in Moz but not IE. Since we have some of these, we have to do
    // it the Moz way.
    if (thisObject->impl().frame()->tree().scopedChild(propertyNameToAtomicString(propertyName))) {
        slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, childFrameGetter);
        return true;
    }

    // FIXME: Search the whole frame hierarchy somewhere around here.
    // We need to test the correct priority order.

    // allow window[1] or parent[1] etc. (#56983)
    unsigned i = propertyName.asIndex();
    if (i < thisObject->impl().frame()->tree().scopedChildCount()) {
        ASSERT(i != PropertyName::NotAnIndex);
        slot.setValue(thisObject, ReadOnly | DontDelete | DontEnum,
            toJS(exec, thisObject->impl().frame()->tree().scopedChild(i)->document()->domWindow()));
        return true;
    }

    if (!allowsAccess) {
        thisObject->printErrorMessage(errorMessage);
        slot.setUndefined();
        return true;
    }

    // Allow shortcuts like 'Image1' instead of document.images.Image1
    Document* document = thisObject->impl().frame()->document();
    if (document->isHTMLDocument()) {
        AtomicStringImpl* atomicPropertyName = findAtomicString(propertyName);
        if (atomicPropertyName && toHTMLDocument(document)->hasWindowNamedItem(*atomicPropertyName)) {
            slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, namedItemGetter);
            return true;
        }
    }

    return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
}

bool JSDOMWindow::getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned index, PropertySlot& slot)
{
    JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(object);

    if (!thisObject->impl().frame()) {
        // FIXME: We should have a message here that explains why the property access/function call was
        // not allowed.
        slot.setUndefined();
        return true;
    }

    // We need to check for cross-domain access here without printing the generic warning message
    // because we always allow access to some function, just different ones depending whether access
    // is allowed.
    String errorMessage;
    bool allowsAccess = shouldAllowAccessToDOMWindow(exec, thisObject->impl(), errorMessage);

    // Look for overrides before looking at any of our own properties, but ignore overrides completely
    // if this is cross-domain access.
    if (allowsAccess && JSGlobalObject::getOwnPropertySlotByIndex(thisObject, exec, index, slot))
        return true;

    PropertyName propertyName = Identifier::from(exec, index);

    // Check for child frames by name before built-in properties to
    // match Mozilla. This does not match IE, but some sites end up
    // naming frames things that conflict with window properties that
    // are in Moz but not IE. Since we have some of these, we have to do
    // it the Moz way.
    if (thisObject->impl().frame()->tree().scopedChild(propertyNameToAtomicString(propertyName))) {
        slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, childFrameGetter);
        return true;
    }

    // Do prototype lookup early so that functions and attributes in the prototype can have
    // precedence over the index and name getters.
    JSValue proto = thisObject->prototype();
    if (proto.isObject()) {
        if (asObject(proto)->getPropertySlot(exec, index, slot)) {
            if (!allowsAccess) {
                thisObject->printErrorMessage(errorMessage);
                slot.setUndefined();
            }
            return true;
        }
    }

    // FIXME: Search the whole frame hierarchy somewhere around here.
    // We need to test the correct priority order.

    // allow window[1] or parent[1] etc. (#56983)
    if (index < thisObject->impl().frame()->tree().scopedChildCount()) {
        ASSERT(index != PropertyName::NotAnIndex);
        slot.setValue(thisObject, ReadOnly | DontDelete | DontEnum,
            toJS(exec, thisObject->impl().frame()->tree().scopedChild(index)->document()->domWindow()));
        return true;
    }

    if (!allowsAccess) {
        thisObject->printErrorMessage(errorMessage);
        slot.setUndefined();
        return true;
    }

    // Allow shortcuts like 'Image1' instead of document.images.Image1
    Document* document = thisObject->impl().frame()->document();
    if (document->isHTMLDocument()) {
        AtomicStringImpl* atomicPropertyName = findAtomicString(propertyName);
        if (atomicPropertyName && toHTMLDocument(document)->hasWindowNamedItem(*atomicPropertyName)) {
            slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, namedItemGetter);
            return true;
        }
    }

    return Base::getOwnPropertySlotByIndex(thisObject, exec, index, slot);
}

void JSDOMWindow::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
{
    JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(cell);
    if (!thisObject->impl().frame())
        return;

    // Optimization: access JavaScript global variables directly before involving the DOM.
    if (thisObject->JSGlobalObject::hasOwnPropertyForWrite(exec, propertyName)) {
        if (BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->impl()))
            JSGlobalObject::put(thisObject, exec, propertyName, value, slot);
        return;
    }

    if (lookupPut(exec, propertyName, thisObject, value, *s_info.propHashTable(exec), slot))
        return;

    if (BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->impl()))
        Base::put(thisObject, exec, propertyName, value, slot);
}

void JSDOMWindow::putByIndex(JSCell* cell, ExecState* exec, unsigned index, JSValue value, bool shouldThrow)
{
    JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(cell);
    if (!thisObject->impl().frame())
        return;

    PropertyName propertyName = Identifier::from(exec, index);

    // Optimization: access JavaScript global variables directly before involving the DOM.
    if (thisObject->JSGlobalObject::hasOwnPropertyForWrite(exec, propertyName)) {
        if (BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->impl()))
            JSGlobalObject::putByIndex(thisObject, exec, index, value, shouldThrow);
        return;
    }

    if (BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->impl()))
        Base::putByIndex(thisObject, exec, index, value, shouldThrow);
}

bool JSDOMWindow::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
{
    JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(cell);
    // Only allow deleting properties by frames in the same origin.
    if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->impl()))
        return false;
    return Base::deleteProperty(thisObject, exec, propertyName);
}

bool JSDOMWindow::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned propertyName)
{
    JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(cell);
    // Only allow deleting properties by frames in the same origin.
    if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->impl()))
        return false;
    return Base::deletePropertyByIndex(thisObject, exec, propertyName);
}

void JSDOMWindow::getPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
    JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(object);
    // Only allow the window to enumerated by frames in the same origin.
    if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->impl()))
        return;
    Base::getPropertyNames(thisObject, exec, propertyNames, mode);
}

void JSDOMWindow::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
    JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(object);
    // Only allow the window to enumerated by frames in the same origin.
    if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->impl()))
        return;
    Base::getOwnPropertyNames(thisObject, exec, propertyNames, mode);
}

bool JSDOMWindow::defineOwnProperty(JSC::JSObject* object, JSC::ExecState* exec, JSC::PropertyName propertyName, const JSC::PropertyDescriptor& descriptor, bool shouldThrow)
{
    JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(object);
    // Only allow defining properties in this way by frames in the same origin, as it allows setters to be introduced.
    if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->impl()))
        return false;

    // Don't allow shadowing location using accessor properties.
    if (descriptor.isAccessorDescriptor() && propertyName == Identifier(exec, "location"))
        return false;

    return Base::defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow);
}

// Custom Attributes

void JSDOMWindow::setLocation(ExecState* exec, JSValue value)
{
#if ENABLE(DASHBOARD_SUPPORT)
    // To avoid breaking old widgets, make "var location =" in a top-level frame create
    // a property named "location" instead of performing a navigation (<rdar://problem/5688039>).
    if (Frame* activeFrame = activeDOMWindow(exec).frame()) {
        if (activeFrame->settings().usesDashboardBackwardCompatibilityMode() && !activeFrame->tree().parent()) {
            if (BindingSecurity::shouldAllowAccessToDOMWindow(exec, impl()))
                putDirect(exec->vm(), Identifier(exec, "location"), value);
            return;
        }
    }
#endif

    String locationString = value.toString(exec)->value(exec);
    if (exec->hadException())
        return;

    if (Location* location = impl().location())
        location->setHref(locationString, activeDOMWindow(exec), firstDOMWindow(exec));
}

JSValue JSDOMWindow::event(ExecState* exec) const
{
    Event* event = currentEvent();
    if (!event)
        return jsUndefined();
    return toJS(exec, const_cast<JSDOMWindow*>(this), event);
}

JSValue JSDOMWindow::image(ExecState* exec) const
{
    return getDOMConstructor<JSImageConstructor>(exec->vm(), this);
}

#if ENABLE(IOS_TOUCH_EVENTS)
JSValue JSDOMWindow::touch(ExecState* exec) const
{
    return getDOMConstructor<JSTouchConstructor>(exec->vm(), this);
}

JSValue JSDOMWindow::touchList(ExecState* exec) const
{
    return getDOMConstructor<JSTouchListConstructor>(exec->vm(), this);
}
#endif

// Custom functions

JSValue JSDOMWindow::open(ExecState* exec)
{
    String urlString = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0));
    if (exec->hadException())
        return jsUndefined();
    AtomicString frameName = exec->argument(1).isUndefinedOrNull() ? "_blank" : exec->argument(1).toString(exec)->value(exec);
    if (exec->hadException())
        return jsUndefined();
    String windowFeaturesString = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(2));
    if (exec->hadException())
        return jsUndefined();

    RefPtr<DOMWindow> openedWindow = impl().open(urlString, frameName, windowFeaturesString, activeDOMWindow(exec), firstDOMWindow(exec));
    if (!openedWindow)
        return jsUndefined();
    return toJS(exec, openedWindow.get());
}

class DialogHandler {
public:
    explicit DialogHandler(ExecState* exec)
        : m_exec(exec)
    {
    }

    void dialogCreated(DOMWindow&);
    JSValue returnValue() const;

private:
    ExecState* m_exec;
    RefPtr<Frame> m_frame;
};

inline void DialogHandler::dialogCreated(DOMWindow& dialog)
{
    m_frame = dialog.frame();

    // FIXME: This looks like a leak between the normal world and an isolated
    //        world if dialogArguments comes from an isolated world.
    JSDOMWindow* globalObject = toJSDOMWindow(m_frame.get(), normalWorld(m_exec->vm()));
    if (JSValue dialogArguments = m_exec->argument(1))
        globalObject->putDirect(m_exec->vm(), Identifier(m_exec, "dialogArguments"), dialogArguments);
}

inline JSValue DialogHandler::returnValue() const
{
    JSDOMWindow* globalObject = toJSDOMWindow(m_frame.get(), normalWorld(m_exec->vm()));
    if (!globalObject)
        return jsUndefined();
    Identifier identifier(m_exec, "returnValue");
    PropertySlot slot(globalObject);
    if (!JSGlobalObject::getOwnPropertySlot(globalObject, m_exec, identifier, slot))
        return jsUndefined();
    return slot.getValue(m_exec, identifier);
}

JSValue JSDOMWindow::showModalDialog(ExecState* exec)
{
    String urlString = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0));
    if (exec->hadException())
        return jsUndefined();
    String dialogFeaturesString = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(2));
    if (exec->hadException())
        return jsUndefined();

    DialogHandler handler(exec);

    impl().showModalDialog(urlString, dialogFeaturesString, activeDOMWindow(exec), firstDOMWindow(exec), [&handler](DOMWindow& dialog) {
        handler.dialogCreated(dialog);
    });

    return handler.returnValue();
}

static JSValue handlePostMessage(DOMWindow* impl, ExecState* exec)
{
    MessagePortArray messagePorts;
    ArrayBufferArray arrayBuffers;

    // This function has variable arguments and can be:
    // Per current spec:
    //   postMessage(message, targetOrigin)
    //   postMessage(message, targetOrigin, {sequence of transferrables})
    // Legacy non-standard implementations in webkit allowed:
    //   postMessage(message, {sequence of transferrables}, targetOrigin);
    int targetOriginArgIndex = 1;
    if (exec->argumentCount() > 2) {
        int transferablesArgIndex = 2;
        if (exec->argument(2).isString()) {
            targetOriginArgIndex = 2;
            transferablesArgIndex = 1;
        }
        fillMessagePortArray(exec, exec->argument(transferablesArgIndex), messagePorts, arrayBuffers);
    }
    if (exec->hadException())
        return jsUndefined();

    RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(exec, exec->argument(0),
                                                                         &messagePorts,
                                                                         &arrayBuffers);

    if (exec->hadException())
        return jsUndefined();

    String targetOrigin = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(targetOriginArgIndex));
    if (exec->hadException())
        return jsUndefined();

    ExceptionCode ec = 0;
    impl->postMessage(message.release(), &messagePorts, targetOrigin, activeDOMWindow(exec), ec);
    setDOMException(exec, ec);

    return jsUndefined();
}

JSValue JSDOMWindow::postMessage(ExecState* exec)
{
    return handlePostMessage(&impl(), exec);
}

JSValue JSDOMWindow::setTimeout(ExecState* exec)
{
    ContentSecurityPolicy* contentSecurityPolicy = impl().document() ? impl().document()->contentSecurityPolicy() : 0;
    std::unique_ptr<ScheduledAction> action = ScheduledAction::create(exec, globalObject()->world(), contentSecurityPolicy);
    if (exec->hadException())
        return jsUndefined();

    if (!action)
        return jsNumber(0);

    int delay = exec->argument(1).toInt32(exec);

    ExceptionCode ec = 0;
    int result = impl().setTimeout(WTF::move(action), delay, ec);
    setDOMException(exec, ec);

    return jsNumber(result);
}

JSValue JSDOMWindow::setInterval(ExecState* exec)
{
    ContentSecurityPolicy* contentSecurityPolicy = impl().document() ? impl().document()->contentSecurityPolicy() : 0;
    std::unique_ptr<ScheduledAction> action = ScheduledAction::create(exec, globalObject()->world(), contentSecurityPolicy);
    if (exec->hadException())
        return jsUndefined();
    int delay = exec->argument(1).toInt32(exec);

    if (!action)
        return jsNumber(0);

    ExceptionCode ec = 0;
    int result = impl().setInterval(WTF::move(action), delay, ec);
    setDOMException(exec, ec);

    return jsNumber(result);
}

JSValue JSDOMWindow::addEventListener(ExecState* exec)
{
    Frame* frame = impl().frame();
    if (!frame)
        return jsUndefined();

    JSValue listener = exec->argument(1);
    if (!listener.isObject())
        return jsUndefined();

    impl().addEventListener(exec->argument(0).toString(exec)->value(exec), JSEventListener::create(asObject(listener), this, false, globalObject()->world()), exec->argument(2).toBoolean(exec));
    return jsUndefined();
}

JSValue JSDOMWindow::removeEventListener(ExecState* exec)
{
    Frame* frame = impl().frame();
    if (!frame)
        return jsUndefined();

    JSValue listener = exec->argument(1);
    if (!listener.isObject())
        return jsUndefined();

    impl().removeEventListener(exec->argument(0).toString(exec)->value(exec), JSEventListener::create(asObject(listener), this, false, globalObject()->world()).get(), exec->argument(2).toBoolean(exec));
    return jsUndefined();
}

DOMWindow* toDOMWindow(JSValue value)
{
    if (!value.isObject())
        return 0;
    JSObject* object = asObject(value);
    if (object->inherits(JSDOMWindow::info()))
        return &jsCast<JSDOMWindow*>(object)->impl();
    if (object->inherits(JSDOMWindowShell::info()))
        return &jsCast<JSDOMWindowShell*>(object)->impl();
    return 0;
}

} // namespace WebCore


text:
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once

#include "map_listener.h"
#include "map_source.h"
#include "mapping_monitor.h"
#include "named_service.h"
#include "proxy_map_source.h"
#include "request_completion_handler.h"
#include "service_map_history.h"
#include "service_mapping.h"

#include <vespa/fnet/task.h>

#include <vector>
#include <memory>
#include <map>

namespace slobrok {

/**
 * @class LocalRpcMonitorMap
 * @brief A collection of ManagedRpcServer objects
 *
 * Tracks up/down status for name->spec combinations
 * that are considered for publication locally.
 **/
class LocalRpcMonitorMap : public MapListener,
                           public MappingMonitorOwner
{
private:
    enum class EventType { ADD, REMOVE };

    struct Event {
        EventType type;
        ServiceMapping mapping;
        static Event add(const ServiceMapping &value) {
            return Event{EventType::ADD, value};
        }
        static Event remove(const ServiceMapping &value) {
            return Event{EventType::REMOVE, value};
        }
    };

    class DelayedTasks : public FNET_Task {
        std::vector<Event>  _queue;
        LocalRpcMonitorMap &_target;
    public:
        void handleLater(Event event) {
            _queue.emplace_back(std::move(event));
            ScheduleNow();
        }

        void PerformTask() override;

        DelayedTasks(FNET_Scheduler *scheduler, LocalRpcMonitorMap &target)
          : FNET_Task(scheduler),
            _queue(),
            _target(target)
        {}

        ~DelayedTasks() { Kill(); }
    };

    DelayedTasks _delayedTasks;

    struct PerService {
        bool up;
        bool localOnly;
        std::unique_ptr<CompletionHandler> inflight;
        vespalib::string spec;
    };

    PerService localService(const ServiceMapping &mapping,
                            std::unique_ptr<CompletionHandler> inflight)
    {
        return PerService{
            .up = false,
            .localOnly = true,
            .inflight = std::move(inflight),
            .spec = mapping.spec
        };
    }

    PerService globalService(const ServiceMapping &mapping) {
        return PerService{
            .up = false,
            .localOnly = false,
            .inflight = {},
            .spec = mapping.spec
        };
    }

    using Map = std::map<vespalib::string, PerService>;

    Map _map;
    ProxyMapSource _dispatcher;
    ServiceMapHistory _history;
    MappingMonitor::UP _mappingMonitor;
    std::unique_ptr<MapSubscription> _subscription;

    void doAdd(const ServiceMapping &mapping);
    void doRemove(const ServiceMapping &mapping);

    PerService & lookup(const ServiceMapping &mapping);

    void addToMap(const ServiceMapping &mapping, PerService psd, bool hurry);

    struct RemovedData {
        ServiceMapping mapping;
        bool up;
        bool localOnly;
        std::unique_ptr<CompletionHandler> inflight;
    };

    RemovedData removeFromMap(Map::iterator iter);

public:
    LocalRpcMonitorMap(FNET_Scheduler *scheduler,
                       MappingMonitorFactory mappingMonitorFactory);
    ~LocalRpcMonitorMap();

    MapSource &dispatcher() { return _dispatcher; }
    ServiceMapHistory & history();

    bool wouldConflict(const ServiceMapping &mapping) const;

    /** for use by register API, will call doneHandler() on inflight script */
    void addLocal(const ServiceMapping &mapping,
                  std::unique_ptr<CompletionHandler> inflight);

    /** for use by unregister API */
    void removeLocal(const ServiceMapping &mapping);

    void add(const ServiceMapping &mapping) override;
    void remove(const ServiceMapping &mapping) override;

    void up(const ServiceMapping& mapping) override;
    void down(const ServiceMapping& mapping) override;
};

//-----------------------------------------------------------------------------

} // namespace slobrok


text:
'use strict';

describe('Author e2e test', function () {

    var username = element(by.id('username'));
    var password = element(by.id('password'));
    var entityMenu = element(by.id('entity-menu'));
    var accountMenu = element(by.id('account-menu'));
    var login = element(by.id('login'));
    var logout = element(by.id('logout'));

    beforeAll(function () {
        browser.get('/');

        accountMenu.click();
        login.click();

        username.sendKeys('admin');
        password.sendKeys('admin');
        element(by.css('button[type=submit]')).click();
    });

    it('should load Authors', function () {
        entityMenu.click();
        element(by.css('[ui-sref="author"]')).click().then(function() {
            expect(element.all(by.css('h2')).first().getText()).toMatch(/Authors/);
        });
    });

    it('should load create Author dialog', function () {
        element(by.css('[ui-sref="author.new"]')).click().then(function() {
            expect(element(by.css('h4.modal-title')).getText()).toMatch(/Create or edit a Author/);
            element(by.css('button.close')).click();
        });
    });

    afterAll(function () {
        accountMenu.click();
        logout.click();
    });
});


text:
use prelude::*;

use num;
use vec;
use str;
use super::{Reader, Writer, Stream, Decorator};

// libuv recommends 64k buffers to maximize throughput
// https://groups.google.com/forum/#!topic/libuv/oQO1HJAIDdA
static DEFAULT_CAPACITY: uint = 64 * 1024;

/// Wraps a Reader and buffers input from it
pub struct BufferedReader<R> {
    priv inner: R,
    priv buf: ~[u8],
    priv pos: uint,
    priv cap: uint
}

impl<R: Reader> BufferedReader<R> {
    /// Creates a new `BufferedReader` with with the specified buffer capacity
    pub fn with_capacity(cap: uint, inner: R) -> BufferedReader<R> {
        BufferedReader {
            inner: inner,
            buf: vec::from_elem(cap, 0u8),
            pos: 0,
            cap: 0
        }
    }

    /// Creates a new `BufferedReader` with a default buffer capacity
    pub fn new(inner: R) -> BufferedReader<R> {
        BufferedReader::with_capacity(DEFAULT_CAPACITY, inner)
    }

    /// Reads the next line of input, interpreted as a sequence of utf-8
    /// encoded unicode codepoints. If a newline is encountered, then the
    /// newline is contained in the returned string.
    pub fn read_line(&mut self) -> Option<~str> {
        self.read_until('\n' as u8).map(str::from_utf8_owned)
    }

    /// Reads a sequence of bytes leading up to a specified delimeter. Once the
    /// specified byte is encountered, reading ceases and the bytes up to and
    /// including the delimiter are returned.
    pub fn read_until(&mut self, byte: u8) -> Option<~[u8]> {
        let mut res = ~[];
        let mut used;
        loop {
            {
                let available = self.fill_buffer();
                match available.iter().position(|&b| b == byte) {
                    Some(i) => {
                        res.push_all(available.slice_to(i + 1));
                        used = i + 1;
                        break
                    }
                    None => {
                        res.push_all(available);
                        used = available.len();
                    }
                }
            }
            if used == 0 {
                break
            }
            self.pos += used;
        }
        self.pos += used;
        return if res.len() == 0 {None} else {Some(res)};
    }

    fn fill_buffer<'a>(&'a mut self) -> &'a [u8] {
        if self.pos == self.cap {
            match self.inner.read(self.buf) {
                Some(cap) => {
                    self.pos = 0;
                    self.cap = cap;
                }
                None => {}
            }
        }
        return self.buf.slice(self.pos, self.cap);
    }
}

impl<R: Reader> Reader for BufferedReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
        let nread = {
            let available = self.fill_buffer();
            if available.len() == 0 {
                return None;
            }
            let nread = num::min(available.len(), buf.len());
            vec::bytes::copy_memory(buf, available, nread);
            nread
        };
        self.pos += nread;
        Some(nread)
    }

    fn eof(&mut self) -> bool {
        self.pos == self.cap && self.inner.eof()
    }
}

impl<R: Reader> Decorator<R> for BufferedReader<R> {
    fn inner(self) -> R {
        self.inner
    }

    fn inner_ref<'a>(&'a self) -> &'a R {
        &self.inner
    }

    fn inner_mut_ref<'a>(&'a mut self) -> &'a mut R {
        &mut self.inner
    }
}

/// Wraps a Writer and buffers output to it
///
/// Note that `BufferedWriter` will NOT flush its buffer when dropped.
pub struct BufferedWriter<W> {
    priv inner: W,
    priv buf: ~[u8],
    priv pos: uint
}

impl<W: Writer> BufferedWriter<W> {
    /// Creates a new `BufferedWriter` with with the specified buffer capacity
    pub fn with_capacity(cap: uint, inner: W) -> BufferedWriter<W> {
        BufferedWriter {
            inner: inner,
            buf: vec::from_elem(cap, 0u8),
            pos: 0
        }
    }

    /// Creates a new `BufferedWriter` with a default buffer capacity
    pub fn new(inner: W) -> BufferedWriter<W> {
        BufferedWriter::with_capacity(DEFAULT_CAPACITY, inner)
    }
}

impl<W: Writer> Writer for BufferedWriter<W> {
    fn write(&mut self, buf: &[u8]) {
        if self.pos + buf.len() > self.buf.len() {
            self.flush();
        }

        if buf.len() > self.buf.len() {
            self.inner.write(buf);
        } else {
            let dst = self.buf.mut_slice_from(self.pos);
            vec::bytes::copy_memory(dst, buf, buf.len());
            self.pos += buf.len();
        }
    }

    fn flush(&mut self) {
        if self.pos != 0 {
            self.inner.write(self.buf.slice_to(self.pos));
            self.pos = 0;
        }
        self.inner.flush();
    }
}

impl<W: Writer> Decorator<W> for BufferedWriter<W> {
    fn inner(self) -> W {
        self.inner
    }

    fn inner_ref<'a>(&'a self) -> &'a W {
        &self.inner
    }

    fn inner_mut_ref<'a>(&'a mut self) -> &'a mut W {
        &mut self.inner
    }
}

struct InternalBufferedWriter<W>(BufferedWriter<W>);

impl<W: Reader> Reader for InternalBufferedWriter<W> {
    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
        self.inner.read(buf)
    }

    fn eof(&mut self) -> bool {
        self.inner.eof()
    }
}

/// Wraps a Stream and buffers input and output to and from it
///
/// Note that `BufferedStream` will NOT flush its output buffer when dropped.
pub struct BufferedStream<S> {
    priv inner: BufferedReader<InternalBufferedWriter<S>>
}

impl<S: Stream> BufferedStream<S> {
    pub fn with_capacities(reader_cap: uint, writer_cap: uint, inner: S)
                           -> BufferedStream<S> {
        let writer = BufferedWriter::with_capacity(writer_cap, inner);
        let internal_writer = InternalBufferedWriter(writer);
        let reader = BufferedReader::with_capacity(reader_cap,
                                                   internal_writer);
        BufferedStream { inner: reader }
    }

    pub fn new(inner: S) -> BufferedStream<S> {
        BufferedStream::with_capacities(DEFAULT_CAPACITY, DEFAULT_CAPACITY,
                                        inner)
    }
}

impl<S: Stream> Reader for BufferedStream<S> {
    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
        self.inner.read(buf)
    }

    fn eof(&mut self) -> bool {
        self.inner.eof()
    }
}

impl<S: Stream> Writer for BufferedStream<S> {
    fn write(&mut self, buf: &[u8]) {
        self.inner.inner.write(buf)
    }

    fn flush(&mut self) {
        self.inner.inner.flush()
    }
}

impl<S: Stream> Decorator<S> for BufferedStream<S> {
    fn inner(self) -> S {
        self.inner.inner.inner()
    }

    fn inner_ref<'a>(&'a self) -> &'a S {
        self.inner.inner.inner_ref()
    }

    fn inner_mut_ref<'a>(&'a mut self) -> &'a mut S {
        self.inner.inner.inner_mut_ref()
    }
}

#[cfg(test)]
mod test {
    use prelude::*;
    use super::*;
    use super::super::mem::{MemReader, MemWriter};

    #[test]
    fn test_buffered_reader() {
        let inner = MemReader::new(~[0, 1, 2, 3, 4]);
        let mut reader = BufferedReader::with_capacity(2, inner);

        let mut buf = [0, 0, 0];
        let nread = reader.read(buf);
        assert_eq!(Some(2), nread);
        assert_eq!([0, 1, 0], buf);
        assert!(!reader.eof());

        let mut buf = [0];
        let nread = reader.read(buf);
        assert_eq!(Some(1), nread);
        assert_eq!([2], buf);
        assert!(!reader.eof());

        let mut buf = [0, 0, 0];
        let nread = reader.read(buf);
        assert_eq!(Some(1), nread);
        assert_eq!([3, 0, 0], buf);
        assert!(!reader.eof());

        let nread = reader.read(buf);
        assert_eq!(Some(1), nread);
        assert_eq!([4, 0, 0], buf);
        assert!(reader.eof());

        assert_eq!(None, reader.read(buf));
    }

    #[test]
    fn test_buffered_writer() {
        let inner = MemWriter::new();
        let mut writer = BufferedWriter::with_capacity(2, inner);

        writer.write([0, 1]);
        assert_eq!([], writer.inner_ref().inner_ref().as_slice());

        writer.write([2]);
        assert_eq!([0, 1], writer.inner_ref().inner_ref().as_slice());

        writer.write([3]);
        assert_eq!([0, 1], writer.inner_ref().inner_ref().as_slice());

        writer.flush();
        assert_eq!([0, 1, 2, 3], writer.inner_ref().inner_ref().as_slice());

        writer.write([4]);
        writer.write([5]);
        assert_eq!([0, 1, 2, 3], writer.inner_ref().inner_ref().as_slice());

        writer.write([6]);
        assert_eq!([0, 1, 2, 3, 4, 5],
                   writer.inner_ref().inner_ref().as_slice());

        writer.write([7, 8]);
        assert_eq!([0, 1, 2, 3, 4, 5, 6],
                   writer.inner_ref().inner_ref().as_slice());

        writer.write([9, 10, 11]);
        assert_eq!([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
                   writer.inner_ref().inner_ref().as_slice());

        writer.flush();
        assert_eq!([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
                   writer.inner_ref().inner_ref().as_slice());
    }

    // This is just here to make sure that we don't infinite loop in the
    // newtype struct autoderef weirdness
    #[test]
    fn test_buffered_stream() {
        use rt;
        struct S;

        impl rt::io::Writer for S {
            fn write(&mut self, _: &[u8]) {}
            fn flush(&mut self) {}
        }

        impl rt::io::Reader for S {
            fn read(&mut self, _: &mut [u8]) -> Option<uint> { None }
            fn eof(&mut self) -> bool { true }
        }

        let mut stream = BufferedStream::new(S);
        let mut buf = [];
        stream.read(buf);
        stream.eof();
        stream.write(buf);
        stream.flush();
    }

    #[test]
    fn test_read_until() {
        let inner = MemReader::new(~[0, 1, 2, 1, 0]);
        let mut reader = BufferedReader::with_capacity(2, inner);
        assert_eq!(reader.read_until(0), Some(~[0]));
        assert_eq!(reader.read_until(2), Some(~[1, 2]));
        assert_eq!(reader.read_until(1), Some(~[1]));
        assert_eq!(reader.read_until(8), Some(~[0]));
        assert_eq!(reader.read_until(9), None);
    }
}