text:
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "base/basictypes.h"
#include "BluetoothAdapter.h"
#include "BluetoothDevice.h"
#include "BluetoothPropertyEvent.h"
#include "BluetoothReplyRunnable.h"
#include "BluetoothService.h"
#include "BluetoothUtils.h"
#include "GeneratedEvents.h"

#include "nsContentUtils.h"
#include "nsDOMClassInfo.h"
#include "nsDOMEvent.h"
#include "nsIDOMBluetoothDeviceAddressEvent.h"
#include "nsIDOMBluetoothDeviceEvent.h"
#include "nsTArrayHelpers.h"
#include "DOMRequest.h"
#include "nsThreadUtils.h"

#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/LazyIdleThread.h"
#include "mozilla/Util.h"

using namespace mozilla;

USING_BLUETOOTH_NAMESPACE

DOMCI_DATA(BluetoothAdapter, BluetoothAdapter)

NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothAdapter)

NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(BluetoothAdapter,
                                               nsDOMEventTargetHelper)
  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsUuids)
  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsDeviceAddresses)
NS_IMPL_CYCLE_COLLECTION_TRACE_END

NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothAdapter,
                                                  nsDOMEventTargetHelper)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END

NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothAdapter,
                                                nsDOMEventTargetHelper)
  tmp->Unroot();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END

NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothAdapter)
  NS_INTERFACE_MAP_ENTRY(nsIDOMBluetoothAdapter)
  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(BluetoothAdapter)
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)

NS_IMPL_ADDREF_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)

class GetDevicesTask : public BluetoothReplyRunnable
{
public:
  GetDevicesTask(BluetoothAdapter* aAdapterPtr,
                       nsIDOMDOMRequest* aReq) :
    BluetoothReplyRunnable(aReq),
    mAdapterPtr(aAdapterPtr)
  {
    MOZ_ASSERT(aReq && aAdapterPtr);
  }

  virtual bool ParseSuccessfulReply(JS::Value* aValue)
  {
    *aValue = JSVAL_VOID;

    const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value();
    if (v.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
      NS_WARNING("Not a BluetoothNamedValue array!");
      SetError(NS_LITERAL_STRING("BluetoothReplyTypeError"));
      return false;
    }

    const InfallibleTArray<BluetoothNamedValue>& values =
      v.get_ArrayOfBluetoothNamedValue();

    nsTArray<nsRefPtr<BluetoothDevice> > devices;
    JSObject* JsDevices;
    for (uint32_t i = 0; i < values.Length(); i++) {
      const BluetoothValue properties = values[i].value();
      if (properties.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
        NS_WARNING("Not a BluetoothNamedValue array!");
        SetError(NS_LITERAL_STRING("BluetoothReplyTypeError"));
        return false;
      }
      nsRefPtr<BluetoothDevice> d =
        BluetoothDevice::Create(mAdapterPtr->GetOwner(),
                                mAdapterPtr->GetPath(),
                                properties);
      devices.AppendElement(d);
    }

    nsresult rv;
    nsIScriptContext* sc = mAdapterPtr->GetContextForEventHandlers(&rv);
    if (!sc) {
      NS_WARNING("Cannot create script context!");
      SetError(NS_LITERAL_STRING("BluetoothScriptContextError"));
      return false;
    }

    rv = nsTArrayToJSArray(sc->GetNativeContext(), devices, &JsDevices);
    if (!JsDevices) {
      NS_WARNING("Cannot create JS array!");
      SetError(NS_LITERAL_STRING("BluetoothError"));
      return false;
    }

    aValue->setObject(*JsDevices);
    return true;
  }

  void
  ReleaseMembers()
  {
    BluetoothReplyRunnable::ReleaseMembers();
    mAdapterPtr = nullptr;
  }
private:
  nsRefPtr<BluetoothAdapter> mAdapterPtr;
};

class GetScoConnectionStatusTask : public BluetoothReplyRunnable
{
public:
  GetScoConnectionStatusTask(nsIDOMDOMRequest* aReq) :
    BluetoothReplyRunnable(aReq)
  {
    MOZ_ASSERT(aReq);
  }

  virtual bool ParseSuccessfulReply(JS::Value* aValue)
  {
    *aValue = JSVAL_VOID;

    const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value();
    if (v.type() != BluetoothValue::Tbool) {
      NS_WARNING("Not a boolean!");
      SetError(NS_LITERAL_STRING("BluetoothReplyTypeError"));
      return false;
    }

    aValue->setBoolean(v.get_bool());
    return true;
  }

  void
  ReleaseMembers()
  {
    BluetoothReplyRunnable::ReleaseMembers();
  }
};

static int kCreatePairedDeviceTimeout = 50000; // unit: msec

nsresult
PrepareDOMRequest(nsIDOMWindow* aWindow, nsIDOMDOMRequest** aRequest)
{
  MOZ_ASSERT(aWindow);

  nsCOMPtr<nsIDOMRequestService> rs =
    do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
  NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE);

  nsresult rv = rs->CreateRequest(aWindow, aRequest);
  NS_ENSURE_SUCCESS(rv, rv);

  return NS_OK;
}

BluetoothAdapter::BluetoothAdapter(nsPIDOMWindow* aWindow,
                                   const BluetoothValue& aValue)
  : BluetoothPropertyContainer(BluetoothObjectType::TYPE_ADAPTER)
  , mDiscoverable(false)
  , mDiscovering(false)
  , mPairable(false)
  , mPowered(false)
  , mJsUuids(nullptr)
  , mJsDeviceAddresses(nullptr)
  , mIsRooted(false)
{
  MOZ_ASSERT(aWindow);

  BindToOwner(aWindow);
  const InfallibleTArray<BluetoothNamedValue>& values =
    aValue.get_ArrayOfBluetoothNamedValue();
  for (uint32_t i = 0; i < values.Length(); ++i) {
    SetPropertyByValue(values[i]);
  }

  BluetoothService* bs = BluetoothService::Get();
  NS_ENSURE_TRUE_VOID(bs);
  bs->RegisterBluetoothSignalHandler(mPath, this);
}

BluetoothAdapter::~BluetoothAdapter()
{
  BluetoothService* bs = BluetoothService::Get();
  // We can be null on shutdown, where this might happen
  NS_ENSURE_TRUE_VOID(bs);
  bs->UnregisterBluetoothSignalHandler(mPath, this);

  Unroot();
}

void
BluetoothAdapter::Unroot()
{
  if (!mIsRooted) {
    return;
  }
  mJsUuids = nullptr;
  mJsDeviceAddresses = nullptr;
  NS_DROP_JS_OBJECTS(this, BluetoothAdapter);
  mIsRooted = false;
}

void
BluetoothAdapter::Root()
{
  if (mIsRooted) {
    return;
  }
  NS_HOLD_JS_OBJECTS(this, BluetoothAdapter);
  mIsRooted = true;
}

void
BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue)
{
  const nsString& name = aValue.name();
  const BluetoothValue& value = aValue.value();
  if (name.EqualsLiteral("Name")) {
    mName = value.get_nsString();
  } else if (name.EqualsLiteral("Address")) {
    mAddress = value.get_nsString();
  } else if (name.EqualsLiteral("Path")) {
    mPath = value.get_nsString();
  } else if (name.EqualsLiteral("Discoverable")) {
    mDiscoverable = value.get_bool();
  } else if (name.EqualsLiteral("Discovering")) {
    mDiscovering = value.get_bool();
  } else if (name.EqualsLiteral("Pairable")) {
    mPairable = value.get_bool();
  } else if (name.EqualsLiteral("Powered")) {
    mPowered = value.get_bool();
  } else if (name.EqualsLiteral("PairableTimeout")) {
    mPairableTimeout = value.get_uint32_t();
  } else if (name.EqualsLiteral("DiscoverableTimeout")) {
    mDiscoverableTimeout = value.get_uint32_t();
  } else if (name.EqualsLiteral("Class")) {
    mClass = value.get_uint32_t();
  } else if (name.EqualsLiteral("UUIDs")) {
    mUuids = value.get_ArrayOfnsString();
    nsresult rv;
    nsIScriptContext* sc = GetContextForEventHandlers(&rv);
    NS_ENSURE_SUCCESS_VOID(rv);

    if (NS_FAILED(nsTArrayToJSArray(sc->GetNativeContext(),
                                    mUuids,
                                    &mJsUuids))) {
      NS_WARNING("Cannot set JS UUIDs object!");
      return;
    }
    Root();
  } else if (name.EqualsLiteral("Devices")) {
    mDeviceAddresses = value.get_ArrayOfnsString();

    uint32_t length = mDeviceAddresses.Length();
    for (int i = 0; i < length; i++) {
      mDeviceAddresses[i] = GetAddressFromObjectPath(mDeviceAddresses[i]);
    }

    nsresult rv;
    nsIScriptContext* sc = GetContextForEventHandlers(&rv);
    NS_ENSURE_SUCCESS_VOID(rv);

    if (NS_FAILED(nsTArrayToJSArray(sc->GetNativeContext(),
                                    mDeviceAddresses,
                                    &mJsDeviceAddresses))) {
      NS_WARNING("Cannot set JS Devices object!");
      return;
    }
    Root();
  } else {
#ifdef DEBUG
    nsCString warningMsg;
    warningMsg.AssignLiteral("Not handling adapter property: ");
    warningMsg.Append(NS_ConvertUTF16toUTF8(name));
    NS_WARNING(warningMsg.get());
#endif
  }
}

// static
already_AddRefed<BluetoothAdapter>
BluetoothAdapter::Create(nsPIDOMWindow* aWindow, const BluetoothValue& aValue)
{
  MOZ_ASSERT(NS_IsMainThread());
  MOZ_ASSERT(aWindow);

  nsRefPtr<BluetoothAdapter> adapter = new BluetoothAdapter(aWindow, aValue);
  return adapter.forget();
}

void
BluetoothAdapter::Notify(const BluetoothSignal& aData)
{
  InfallibleTArray<BluetoothNamedValue> arr;

  BT_LOG("[A] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aData.name()).get());

  if (aData.name().EqualsLiteral("DeviceFound")) {
    nsRefPtr<BluetoothDevice> device = BluetoothDevice::Create(GetOwner(), mPath, aData.value());
    nsCOMPtr<nsIDOMEvent> event;
    NS_NewDOMBluetoothDeviceEvent(getter_AddRefs(event), nullptr, nullptr);

    nsCOMPtr<nsIDOMBluetoothDeviceEvent> e = do_QueryInterface(event);
    e->InitBluetoothDeviceEvent(NS_LITERAL_STRING("devicefound"),
                                false, false, device);
    DispatchTrustedEvent(event);
  } else if (aData.name().EqualsLiteral("DeviceDisappeared")) {
    const nsAString& deviceAddress = aData.value().get_nsString();

    nsCOMPtr<nsIDOMEvent> event;
    NS_NewDOMBluetoothDeviceAddressEvent(getter_AddRefs(event), nullptr, nullptr);

    nsCOMPtr<nsIDOMBluetoothDeviceAddressEvent> e = do_QueryInterface(event);
    e->InitBluetoothDeviceAddressEvent(NS_LITERAL_STRING("devicedisappeared"),
                                       false, false, deviceAddress);
    DispatchTrustedEvent(e);
  } else if (aData.name().EqualsLiteral("DeviceCreated")) {
    NS_ASSERTION(aData.value().type() == BluetoothValue::TArrayOfBluetoothNamedValue,
                 "DeviceCreated: Invalid value type");

    nsRefPtr<BluetoothDevice> device = BluetoothDevice::Create(GetOwner(),
                                                               GetPath(),
                                                               aData.value());
    nsCOMPtr<nsIDOMEvent> event;
    NS_NewDOMBluetoothDeviceEvent(getter_AddRefs(event), nullptr, nullptr);

    nsCOMPtr<nsIDOMBluetoothDeviceEvent> e = do_QueryInterface(event);
    e->InitBluetoothDeviceEvent(NS_LITERAL_STRING("devicecreated"),
                                false, false, device);
    DispatchTrustedEvent(e);
  } else if (aData.name().EqualsLiteral("PropertyChanged")) {
    NS_ASSERTION(aData.value().type() == BluetoothValue::TArrayOfBluetoothNamedValue,
                 "PropertyChanged: Invalid value type");
    arr = aData.value().get_ArrayOfBluetoothNamedValue();

    NS_ASSERTION(arr.Length() == 1, "Got more than one property in a change message!");
    BluetoothNamedValue v = arr[0];

    SetPropertyByValue(v);
    nsRefPtr<BluetoothPropertyEvent> e = BluetoothPropertyEvent::Create(v.name());
    e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("propertychanged"));
  } else {
#ifdef DEBUG
    nsCString warningMsg;
    warningMsg.AssignLiteral("Not handling adapter signal: ");
    warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
    NS_WARNING(warningMsg.get());
#endif
  }
}

nsresult
BluetoothAdapter::StartStopDiscovery(bool aStart, nsIDOMDOMRequest** aRequest)
{
  nsCOMPtr<nsIDOMDOMRequest> req;
  nsresult rv;
  rv = PrepareDOMRequest(GetOwner(), getter_AddRefs(req));
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  nsRefPtr<BluetoothVoidReplyRunnable> results =
    new BluetoothVoidReplyRunnable(req);

  BluetoothService* bs = BluetoothService::Get();
  NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
  if (aStart) {
    rv = bs->StartDiscoveryInternal(mPath, results);
  } else {
    rv = bs->StopDiscoveryInternal(mPath, results);
  }
  if(NS_FAILED(rv)) {
    NS_WARNING("Start/Stop Discovery failed!");
    return NS_ERROR_FAILURE;
  }

  // mDiscovering is not set here, we'll get a Property update from our external
  // protocol to tell us that it's been set.
  req.forget(aRequest);
  return NS_OK;
}

NS_IMETHODIMP
BluetoothAdapter::StartDiscovery(nsIDOMDOMRequest** aRequest)
{
  return StartStopDiscovery(true, aRequest);
}

NS_IMETHODIMP
BluetoothAdapter::StopDiscovery(nsIDOMDOMRequest** aRequest)
{
  return StartStopDiscovery(false, aRequest);
}

NS_IMETHODIMP
BluetoothAdapter::GetAddress(nsAString& aAddress)
{
  aAddress = mAddress;
  return NS_OK;
}

NS_IMETHODIMP
BluetoothAdapter::GetAdapterClass(uint32_t* aClass)
{
  *aClass = mClass;
  return NS_OK;
}

NS_IMETHODIMP
BluetoothAdapter::GetDiscovering(bool* aDiscovering)
{
  *aDiscovering = mDiscovering;
  return NS_OK;
}

NS_IMETHODIMP
BluetoothAdapter::GetName(nsAString& aName)
{
  aName = mName;
  return NS_OK;
}

NS_IMETHODIMP
BluetoothAdapter::GetDiscoverable(bool* aDiscoverable)
{
  *aDiscoverable = mDiscoverable;
  return NS_OK;
}

NS_IMETHODIMP
BluetoothAdapter::GetDiscoverableTimeout(uint32_t* aDiscoverableTimeout)
{
  *aDiscoverableTimeout = mDiscoverableTimeout;
  return NS_OK;
}

NS_IMETHODIMP
BluetoothAdapter::GetDevices(JSContext* aCx, JS::Value* aDevices)
{
  if (mJsDeviceAddresses) {
    aDevices->setObject(*mJsDeviceAddresses);
  }
  else {
    NS_WARNING("Devices not yet set!\n");
    return NS_ERROR_FAILURE;
  }
  return NS_OK;
}

NS_IMETHODIMP
BluetoothAdapter::GetUuids(JSContext* aCx, JS::Value* aValue)
{
  if (mJsUuids) {
    aValue->setObject(*mJsUuids);
  }
  else {
    NS_WARNING("UUIDs not yet set!\n");
    return NS_ERROR_FAILURE;
  }
  return NS_OK;
}

NS_IMETHODIMP
BluetoothAdapter::SetName(const nsAString& aName,
                          nsIDOMDOMRequest** aRequest)
{
  if (mName.Equals(aName)) {
    return FirePropertyAlreadySet(GetOwner(), aRequest);
  }
  nsString name(aName);
  BluetoothValue value(name);
  BluetoothNamedValue property(NS_LITERAL_STRING("Name"), value);
  return SetProperty(GetOwner(), property, aRequest);
}

NS_IMETHODIMP
BluetoothAdapter::SetDiscoverable(const bool aDiscoverable,
                                  nsIDOMDOMRequest** aRequest)
{
  if (aDiscoverable == mDiscoverable) {
    return FirePropertyAlreadySet(GetOwner(), aRequest);
  }
  BluetoothValue value(aDiscoverable);
  BluetoothNamedValue property(NS_LITERAL_STRING("Discoverable"), value);
  return SetProperty(GetOwner(), property, aRequest);
}

NS_IMETHODIMP
BluetoothAdapter::SetDiscoverableTimeout(const uint32_t aDiscoverableTimeout,
                                         nsIDOMDOMRequest** aRequest)
{
  if (aDiscoverableTimeout == mDiscoverableTimeout) {
    return FirePropertyAlreadySet(GetOwner(), aRequest);
  }
  BluetoothValue value(aDiscoverableTimeout);
  BluetoothNamedValue property(NS_LITERAL_STRING("DiscoverableTimeout"), value);
  return SetProperty(GetOwner(), property, aRequest);
}

NS_IMETHODIMP
BluetoothAdapter::GetConnectedDevices(uint16_t aProfileId,
                                      nsIDOMDOMRequest** aRequest)
{
  MOZ_ASSERT(NS_IsMainThread());

  nsCOMPtr<nsIDOMDOMRequest> req;
  nsresult rv = PrepareDOMRequest(GetOwner(), getter_AddRefs(req));
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  nsRefPtr<BluetoothReplyRunnable> results =
    new GetDevicesTask(this, req);

  BluetoothService* bs = BluetoothService::Get();
  NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
  rv = bs->GetConnectedDevicePropertiesInternal(aProfileId, results);
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  req.forget(aRequest);
  return NS_OK;
}

NS_IMETHODIMP
BluetoothAdapter::GetPairedDevices(nsIDOMDOMRequest** aRequest)
{
  nsCOMPtr<nsIDOMDOMRequest> req;
  nsresult rv = PrepareDOMRequest(GetOwner(), getter_AddRefs(req));
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  nsRefPtr<BluetoothReplyRunnable> results =
    new GetDevicesTask(this, req);

  BluetoothService* bs = BluetoothService::Get();
  NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
  rv = bs->GetPairedDevicePropertiesInternal(mDeviceAddresses, results);
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  req.forget(aRequest);
  return NS_OK;
}

nsresult
BluetoothAdapter::PairUnpair(bool aPair,
                             nsIDOMBluetoothDevice* aDevice,
                             nsIDOMDOMRequest** aRequest)
{
  nsCOMPtr<nsIDOMDOMRequest> req;
  nsresult rv = PrepareDOMRequest(GetOwner(), getter_AddRefs(req));
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  nsRefPtr<BluetoothVoidReplyRunnable> results =
    new BluetoothVoidReplyRunnable(req);

  nsAutoString addr;
  aDevice->GetAddress(addr);

  BluetoothService* bs = BluetoothService::Get();
  NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
  if (aPair) {
    rv = bs->CreatePairedDeviceInternal(mPath,
                                        addr,
                                        kCreatePairedDeviceTimeout,
                                        results);
  } else {
    rv = bs->RemoveDeviceInternal(mPath, addr, results);
  }

  if (NS_FAILED(rv)) {
    NS_WARNING("Pair/Unpair failed!");
    return NS_ERROR_FAILURE;
  }

  req.forget(aRequest);
  return NS_OK;
}

nsresult
BluetoothAdapter::Pair(nsIDOMBluetoothDevice* aDevice,
                       nsIDOMDOMRequest** aRequest)
{
  return PairUnpair(true, aDevice, aRequest);
}

nsresult
BluetoothAdapter::Unpair(nsIDOMBluetoothDevice* aDevice,
                         nsIDOMDOMRequest** aRequest)
{
  return PairUnpair(false, aDevice, aRequest);
}

nsresult
BluetoothAdapter::SetPinCode(const nsAString& aDeviceAddress,
                             const nsAString& aPinCode,
                             nsIDOMDOMRequest** aRequest)
{
  nsCOMPtr<nsIDOMDOMRequest> req;
  nsresult rv = PrepareDOMRequest(GetOwner(), getter_AddRefs(req));
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  nsRefPtr<BluetoothVoidReplyRunnable> results =
    new BluetoothVoidReplyRunnable(req);

  BluetoothService* bs = BluetoothService::Get();
  NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
  if(!bs->SetPinCodeInternal(aDeviceAddress, aPinCode, results)) {
    NS_WARNING("SetPinCode failed!");
    return NS_ERROR_FAILURE;
  }

  req.forget(aRequest);
  return NS_OK;
}

nsresult
BluetoothAdapter::SetPasskey(const nsAString& aDeviceAddress, uint32_t aPasskey,
                             nsIDOMDOMRequest** aRequest)
{
  nsCOMPtr<nsIDOMDOMRequest> req;
  nsresult rv = PrepareDOMRequest(GetOwner(), getter_AddRefs(req));
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  nsRefPtr<BluetoothVoidReplyRunnable> results =
    new BluetoothVoidReplyRunnable(req);

  BluetoothService* bs = BluetoothService::Get();
  NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
  if(bs->SetPasskeyInternal(aDeviceAddress, aPasskey, results)) {
    NS_WARNING("SetPasskeyInternal failed!");
    return NS_ERROR_FAILURE;
  }

  req.forget(aRequest);
  return NS_OK;
}

nsresult
BluetoothAdapter::SetPairingConfirmation(const nsAString& aDeviceAddress,
                                         bool aConfirmation,
                                         nsIDOMDOMRequest** aRequest)
{
  nsCOMPtr<nsIDOMDOMRequest> req;
  nsresult rv = PrepareDOMRequest(GetOwner(), getter_AddRefs(req));
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  nsRefPtr<BluetoothVoidReplyRunnable> results =
    new BluetoothVoidReplyRunnable(req);

  BluetoothService* bs = BluetoothService::Get();
  NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
  if(!bs->SetPairingConfirmationInternal(aDeviceAddress,
                                         aConfirmation,
                                         results)) {
    NS_WARNING("SetPairingConfirmation failed!");
    return NS_ERROR_FAILURE;
  }

  req.forget(aRequest);
  return NS_OK;
}

nsresult
BluetoothAdapter::SetAuthorization(const nsAString& aDeviceAddress, bool aAllow,
                                   nsIDOMDOMRequest** aRequest)
{
  nsCOMPtr<nsIDOMDOMRequest> req;
  nsresult rv = PrepareDOMRequest(GetOwner(), getter_AddRefs(req));
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  nsRefPtr<BluetoothVoidReplyRunnable> results =
    new BluetoothVoidReplyRunnable(req);

  BluetoothService* bs = BluetoothService::Get();
  NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
  if(!bs->SetAuthorizationInternal(aDeviceAddress, aAllow, results)) {
    NS_WARNING("SetAuthorization failed!");
    return NS_ERROR_FAILURE;
  }

  req.forget(aRequest);
  return NS_OK;
}

NS_IMETHODIMP
BluetoothAdapter::Connect(const nsAString& aDeviceAddress,
                          uint16_t aProfileId,
                          nsIDOMDOMRequest** aRequest)
{
  nsCOMPtr<nsIDOMDOMRequest> req;
  nsresult rv = PrepareDOMRequest(GetOwner(), getter_AddRefs(req));
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  BluetoothService* bs = BluetoothService::Get();
  NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);

  nsRefPtr<BluetoothVoidReplyRunnable> results =
    new BluetoothVoidReplyRunnable(req);
  bs->Connect(aDeviceAddress, mPath, aProfileId, results);

  req.forget(aRequest);
  return NS_OK;
}

NS_IMETHODIMP
BluetoothAdapter::Disconnect(uint16_t aProfileId,
                             nsIDOMDOMRequest** aRequest)
{
  nsCOMPtr<nsIDOMDOMRequest> req;
  nsresult rv = PrepareDOMRequest(GetOwner(), getter_AddRefs(req));
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  nsRefPtr<BluetoothVoidReplyRunnable> results =
    new BluetoothVoidReplyRunnable(req);

  BluetoothService* bs = BluetoothService::Get();
  NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
  bs->Disconnect(aProfileId, results);

  req.forget(aRequest);
  return NS_OK;
}

NS_IMETHODIMP
BluetoothAdapter::SendFile(const nsAString& aDeviceAddress,
                           nsIDOMBlob* aBlob,
                           nsIDOMDOMRequest** aRequest)
{
  nsCOMPtr<nsIDOMDOMRequest> req;
  nsresult rv = PrepareDOMRequest(GetOwner(), getter_AddRefs(req));
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  nsRefPtr<BluetoothVoidReplyRunnable> results =
    new BluetoothVoidReplyRunnable(req);

  BlobChild* actor =
    mozilla::dom::ContentChild::GetSingleton()->GetOrCreateActorForBlob(aBlob);
  if (!actor) {
    NS_WARNING("Can't create actor");
    return NS_ERROR_FAILURE;
  }

  BluetoothService* bs = BluetoothService::Get();
  NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
  bs->SendFile(aDeviceAddress, nullptr, actor, results);

  req.forget(aRequest);
  return NS_OK;
}

NS_IMETHODIMP
BluetoothAdapter::StopSendingFile(const nsAString& aDeviceAddress,
                                  nsIDOMDOMRequest** aRequest)
{
  nsCOMPtr<nsIDOMDOMRequest> req;
  nsresult rv = PrepareDOMRequest(GetOwner(), getter_AddRefs(req));
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  nsRefPtr<BluetoothVoidReplyRunnable> results =
    new BluetoothVoidReplyRunnable(req);

  BluetoothService* bs = BluetoothService::Get();
  NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
  bs->StopSendingFile(aDeviceAddress, results);

  req.forget(aRequest);
  return NS_OK;
}

nsresult
BluetoothAdapter::ConfirmReceivingFile(const nsAString& aDeviceAddress,
                                       bool aConfirmation,
                                       nsIDOMDOMRequest** aRequest)
{
  nsCOMPtr<nsIDOMDOMRequest> req;
  nsresult rv = PrepareDOMRequest(GetOwner(), getter_AddRefs(req));
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  nsRefPtr<BluetoothVoidReplyRunnable> results =
    new BluetoothVoidReplyRunnable(req);

  BluetoothService* bs = BluetoothService::Get();
  NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
  bs->ConfirmReceivingFile(aDeviceAddress, aConfirmation, results);

  req.forget(aRequest);
  return NS_OK;
}

NS_IMETHODIMP
BluetoothAdapter::ConnectSco(nsIDOMDOMRequest** aRequest)
{
  nsCOMPtr<nsIDOMDOMRequest> req;
  nsresult rv = PrepareDOMRequest(GetOwner(), getter_AddRefs(req));
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  nsRefPtr<BluetoothVoidReplyRunnable> results =
    new BluetoothVoidReplyRunnable(req);

  BluetoothService* bs = BluetoothService::Get();
  NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
  bs->ConnectSco(results);

  req.forget(aRequest);
  return NS_OK;
}

NS_IMETHODIMP
BluetoothAdapter::DisconnectSco(nsIDOMDOMRequest** aRequest)
{
  BluetoothService* bs = BluetoothService::Get();
  if (!bs) {
    NS_WARNING("BluetoothService not available!");
    return NS_ERROR_FAILURE;
  }

  nsCOMPtr<nsIDOMRequestService> rs =
    do_GetService("@mozilla.org/dom/dom-request-service;1");

  if (!rs) {
    NS_WARNING("No DOMRequest Service!");
    return NS_ERROR_FAILURE;
  }

  nsCOMPtr<nsIDOMDOMRequest> req;
  nsresult rv = rs->CreateRequest(GetOwner(), getter_AddRefs(req));
  if (NS_FAILED(rv)) {
    NS_WARNING("Can't create DOMRequest!");
    return NS_ERROR_FAILURE;
  }

  nsRefPtr<BluetoothVoidReplyRunnable> result =
    new BluetoothVoidReplyRunnable(req);
  bs->DisconnectSco(result);

  req.forget(aRequest);

  return NS_OK;
}

NS_IMETHODIMP
BluetoothAdapter::IsScoConnected(nsIDOMDOMRequest** aRequest)
{
  BluetoothService* bs = BluetoothService::Get();
  if (!bs) {
    NS_WARNING("BluetoothService not available!");
    return NS_ERROR_FAILURE;
  }

  nsCOMPtr<nsIDOMRequestService> rs =
    do_GetService("@mozilla.org/dom/dom-request-service;1");

  if (!rs) {
    NS_WARNING("No DOMRequest Service!");
    return NS_ERROR_FAILURE;
  }

  nsCOMPtr<nsIDOMDOMRequest> req;
  nsresult rv = rs->CreateRequest(GetOwner(), getter_AddRefs(req));
  if (NS_FAILED(rv)) {
    NS_WARNING("Can't create DOMRequest!");
    return NS_ERROR_FAILURE;
  }

  nsRefPtr<BluetoothReplyRunnable> result =
    new GetScoConnectionStatusTask(req);
  bs->IsScoConnected(result);

  req.forget(aRequest);

  return NS_OK;
}

NS_IMPL_EVENT_HANDLER(BluetoothAdapter, propertychanged)
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, devicefound)
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, devicedisappeared)
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, devicecreated)
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, requestconfirmation)
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, requestpincode)
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, requestpasskey)
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, authorize)
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, cancel)


text:
#include <aws/chime/model/StartMeetingTranscriptionResult.h>
#include <aws/core/utils/json/JsonSerializer.h>
#include <aws/core/AmazonWebServiceResult.h>
#include <aws/core/utils/StringUtils.h>
#include <aws/core/utils/UnreferencedParam.h>

#include <utility>

using namespace Aws::Chime::Model;
using namespace Aws::Utils::Json;
using namespace Aws::Utils;
using namespace Aws;

StartMeetingTranscriptionResult::StartMeetingTranscriptionResult()
{
}

StartMeetingTranscriptionResult::StartMeetingTranscriptionResult(const Aws::AmazonWebServiceResult<JsonValue>& result)
{
  *this = result;
}

StartMeetingTranscriptionResult& StartMeetingTranscriptionResult::operator =(const Aws::AmazonWebServiceResult<JsonValue>& result)
{
  AWS_UNREFERENCED_PARAM(result);

  return *this;
}

redpajama_set_name: RedPajamaGithub


text:
import connection as vdc
import os
from libcloud.compute.deployment import ScriptDeployment
import allocate_ip_and_port_forwarding_rules as nodeCreator

#Assigning the connection driver
driver = vdc.getConn()

#Assigning the node to bootstrap on it
node = nodeCreator.nodeCreator.getNode()

#Defining the shell script which installs chef on a unix-based system
BOOTSTRAP_SCRIPT = ''' #!/usr/bin/env bash
curl -L https://www.opscode.com/chef/install.sh | sudo bash
'''
script = ScriptDeployment(script=BOOTSTRAP_SCRIPT)

#Run the shell script on the node
print 'Running shell script on node: ' + node.name
driver._connect_and_run_deployment_script(node=node,task=script,  ssh_hostname=node.public_ips[0], ssh_port=22,ssh_username='root', ssh_password=node.extra['password'], ssh_key_file=None, ssh_timeout=10, timeout=600, max_tries=3 )
print script.stdout


text:
#include "origen/test_method/functional_test.hpp"

class OrigenFunctionalTest : public Origen::TestMethod::FunctionalTest {
 protected:
  string mPort;

 protected:
  /**
   *Initialize the parameter interface to the testflow.
   *This method is called just once after a testsuite is created.
   */
  virtual void init() {
    // NOTE: The capture arguments are not listed here since it makes no sense
    // to use them without
    //       corresponding functions to handle the captured data

    addParameter("port", "string", &mPort, testmethod::TM_PARAMETER_INPUT)
        .setDefault("")
        .setComment("Port the pattern is to be executed on");
  }

  virtual void body() { origen.port(mPort).execute(); }
};
REGISTER_TESTMETHOD("FunctionalTest", OrigenFunctionalTest);


text:
<?php

namespace Laralum\Files\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Laralum\Files\Models\File;
use Laralum\Users\Models\User;

class FileController extends Controller
{
    public function index()
    {
        $files = File::orderByDesc('id')->paginate(50);

        return view('laralum_files::laralum.index', ['files' => $files]);
    }

    public function upload()
    {
        return view('laralum_files::laralum.upload');
    }

    public function save(Request $request)
    {
        $file = $request->file('file');

        $this->validate($request, [
            'file'   => 'file',
            'public' => 'required|boolean',
        ]);

        $user = User::findOrFail(Auth::id());

        $fileORM = File::create([
            'name'    => str_limit(rtrim($file->getClientOriginalName(), '.'.$file->getClientOriginalExtension()), 191, ''),
            'user_id' => Auth::id(),
            'public'  => $user->can('publish', File::class) ? $request->public : false,
        ]);

        $fileORM->update([
            'real_name' => $fileORM->id.'.'.$file->getClientOriginalExtension(),
        ]);

        $name = $fileORM->id.'.'.$file->getClientOriginalExtension();

        Storage::putFileAs('laralum/files', $file, $name);

        return route('laralum::files.display', ['file' => $fileORM]);
    }

    public function edit(File $file)
    {
        return view('laralum_files::laralum.edit', ['file' => $file]);
    }

    public function update(Request $request, File $file)
    {
        $this->authorize('update', File::class);
        $this->validate($request, [
            'name'   => 'required|max:191',
            'public' => 'required|boolean',
        ]);

        $user = User::findOrFail(Auth::id());

        $file->update([
            'name'    => $request->name,
            'public'  => $user->can('publish', File::class) ? $request->public : false,
        ]);
        $file->touch();

        return redirect()->route('laralum::files.index')->with('success', __('laralum_files::general.file_updated', ['name' => $file->name]));
    }

    public function confirmDestroy(File $file)
    {
        return view('laralum::pages.confirmation', [
            'method'  => 'DELETE',
            'message' => __('laralum_files::general.sure_del_file', ['name' => $file->name]),
            'action'  => route('laralum::files.destroy', ['file' => $file->id]),
        ]);
    }

    public function display(File $file)
    {
        $file->increment('views');

        if (!$file->public) {
            $this->authorize('view', File::class);
        }

        return response()->file($file->getPath(true));
    }

    public function download(File $file)
    {
        $file->increment('downloads');

        return response()->download($file->getPath(true), $file->name.'.'.$file->extension());
    }

    public function destroy(File $file)
    {
        Storage::delete($file->getPath());
        $file->delete();

        return redirect()->route('laralum::files.index')->with('success', __('laralum_files::general.file_deleted', ['name' => $file->name]));
    }
}


text:
const includes = require('lodash/includes');
const exec = require('shell-utils').exec;

const android = includes(process.argv, '--android');
const release = includes(process.argv, '--release');

function run() {
  if (android) {
    runAndroidUnitTests();
  } else {
    runIosUnitTests();
  }
}

function runAndroidUnitTests() {
  const conf = release ? 'testReactNative63ReleaseUnitTest' : 'testReactNative63DebugUnitTest';
  if (android && process.env.JENKINS_CI) {
    const sdkmanager = '/usr/local/share/android-sdk/tools/bin/sdkmanager';
    exec.execSync(`yes | ${sdkmanager} --licenses`);
    // exec.execSync(`echo y | ${sdkmanager} --update && echo y | ${sdkmanager} --licenses`);
  }
  exec.execSync(`cd lib/android && ./gradlew ${conf}`);
}

function runIosUnitTests() {
  exec.execSync('npm run build');
  exec.execSync('npm run pod-install');
  testTarget('playground', 'iPhone 11');
  testTarget('playgroundIOS12', 'iPhone X', '12.2');
}

function testTarget(scheme, device, OS = 'latest') {
  const conf = release ? `Release` : `Debug`;
  exec.execSync(`cd ./playground/ios &&
  RCT_NO_LAUNCH_PACKAGER=true
  xcodebuild build build-for-testing
  -scheme "${scheme}"
  -workspace playground.xcworkspace
  -sdk iphonesimulator
  -configuration ${conf}
  -derivedDataPath ./DerivedData/playground
  -quiet
  -UseModernBuildSystem=NO
  ONLY_ACTIVE_ARCH=YES`);

  exec.execSync(`cd ./playground/ios &&
  RCT_NO_LAUNCH_PACKAGER=true
  xcodebuild test-without-building
  -scheme "${scheme}"
  -workspace playground.xcworkspace
  -sdk iphonesimulator
  -configuration ${conf}
  -destination 'platform=iOS Simulator,name=${device},OS=${OS}'
  -derivedDataPath ./DerivedData/playground
  ONLY_ACTIVE_ARCH=YES`);
}

run();


text:
package org.apache.lucene.search;

import java.io.IOException;
import java.util.BitSet;

import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.TimeLimitingCollector.TimeExceededException;
import org.apache.lucene.search.TimeLimitingCollector.TimerThread;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.Counter;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.ThreadInterruptedException;

/**
 * Tests the {@link TimeLimitingCollector}.  This test checks (1) search
 * correctness (regardless of timeout), (2) expected timeout behavior,
 * and (3) a sanity test with multiple searching threads.
 */
public class TestTimeLimitingCollector extends LuceneTestCase {
  private static final int SLOW_DOWN = 3;
  private static final long TIME_ALLOWED = 17 * SLOW_DOWN; // so searches can find about 17 docs.

  // max time allowed is relaxed for multithreading tests.
  // the multithread case fails when setting this to 1 (no slack) and launching many threads (>2000).
  // but this is not a real failure, just noise.
  private static final double MULTI_THREAD_SLACK = 7;

  private static final int N_DOCS = 3000;
  private static final int N_THREADS = 50;

  private IndexSearcher searcher;
  private Directory directory;
  private IndexReader reader;

  private final String FIELD_NAME = "body";
  private Query query;
  private Counter counter;
  private TimerThread counterThread;

  /**
   * initializes searcher with a document set
   */
  @Override
  public void setUp() throws Exception {
    super.setUp();
    counter = Counter.newCounter(true);
    counterThread = new TimerThread(counter);
    counterThread.start();
    final String docText[] = {
        "docThatNeverMatchesSoWeCanRequireLastDocCollectedToBeGreaterThanZero",
        "one blah three",
        "one foo three multiOne",
        "one foobar three multiThree",
        "blueberry pancakes",
        "blueberry pie",
        "blueberry strudel",
        "blueberry pizza",
    };
    directory = newDirectory();
    RandomIndexWriter iw = new RandomIndexWriter(random(), directory, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())).setMergePolicy(newLogMergePolicy()));

    for (int i=0; i<N_DOCS; i++) {
      add(docText[i%docText.length], iw);
    }
    reader = iw.getReader();
    iw.close();
    searcher = newSearcher(reader);

    BooleanQuery booleanQuery = new BooleanQuery();
    booleanQuery.add(new TermQuery(new Term(FIELD_NAME, "one")), BooleanClause.Occur.SHOULD);
    // start from 1, so that the 0th doc never matches
    for (int i = 1; i < docText.length; i++) {
      String[] docTextParts = docText[i].split("\\s+");
      for (String docTextPart : docTextParts) { // large query so that search will be longer
        booleanQuery.add(new TermQuery(new Term(FIELD_NAME, docTextPart)), BooleanClause.Occur.SHOULD);
      }
    }

    query = booleanQuery;

    // warm the searcher
    searcher.search(query, null, 1000);
  }

  @Override
  public void tearDown() throws Exception {
    reader.close();
    directory.close();
    counterThread.stopTimer();
    counterThread.join();
    super.tearDown();
  }

  private void add(String value, RandomIndexWriter iw) throws IOException {
    Document d = new Document();
    d.add(newTextField(FIELD_NAME, value, Field.Store.NO));
    iw.addDocument(d);
  }

  private void search(Collector collector) throws Exception {
    searcher.search(query, collector);
  }

  /**
   * test search correctness with no timeout
   */
  public void testSearch() {
    doTestSearch();
  }

  private void doTestSearch() {
    int totalResults = 0;
    int totalTLCResults = 0;
    try {
      MyHitCollector myHc = new MyHitCollector();
      search(myHc);
      totalResults = myHc.hitCount();

      myHc = new MyHitCollector();
      long oneHour = 3600000;
      Collector tlCollector = createTimedCollector(myHc, oneHour, false);
      search(tlCollector);
      totalTLCResults = myHc.hitCount();
    } catch (Exception e) {
      e.printStackTrace();
      assertTrue("Unexpected exception: "+e, false); //==fail
    }
    assertEquals( "Wrong number of results!", totalResults, totalTLCResults );
  }

  private Collector createTimedCollector(MyHitCollector hc, long timeAllowed, boolean greedy) {
    TimeLimitingCollector res = new TimeLimitingCollector(hc, counter, timeAllowed);
    res.setGreedy(greedy); // set to true to make sure at least one doc is collected.
    return res;
  }

  /**
   * Test that timeout is obtained, and soon enough!
   */
  public void testTimeoutGreedy() {
    doTestTimeout(false, true);
  }

  /**
   * Test that timeout is obtained, and soon enough!
   */
  public void testTimeoutNotGreedy() {
    doTestTimeout(false, false);
  }

  private void doTestTimeout(boolean multiThreaded, boolean greedy) {
    // setup
    MyHitCollector myHc = new MyHitCollector();
    myHc.setSlowDown(SLOW_DOWN);
    Collector tlCollector = createTimedCollector(myHc, TIME_ALLOWED, greedy);

    // search
    TimeExceededException timoutException = null;
    try {
      search(tlCollector);
    } catch (TimeExceededException x) {
      timoutException = x;
    } catch (Exception e) {
      assertTrue("Unexpected exception: "+e, false); //==fail
    }

    // must get exception
    assertNotNull( "Timeout expected!", timoutException );

    // greediness affect last doc collected
    int exceptionDoc = timoutException.getLastDocCollected();
    int lastCollected = myHc.getLastDocCollected();
    assertTrue( "doc collected at timeout must be > 0!", exceptionDoc > 0 );
    if (greedy) {
      assertTrue("greedy="+greedy+" exceptionDoc="+exceptionDoc+" != lastCollected="+lastCollected, exceptionDoc==lastCollected);
      assertTrue("greedy, but no hits found!", myHc.hitCount() > 0 );
    } else {
      assertTrue("greedy="+greedy+" exceptionDoc="+exceptionDoc+" not > lastCollected="+lastCollected, exceptionDoc>lastCollected);
    }

    // verify that elapsed time at exception is within valid limits
    assertEquals( timoutException.getTimeAllowed(), TIME_ALLOWED);
    // a) Not too early
    assertTrue ( "elapsed="+timoutException.getTimeElapsed()+" <= (allowed-resolution)="+(TIME_ALLOWED-counterThread.getResolution()),
        timoutException.getTimeElapsed() > TIME_ALLOWED-counterThread.getResolution());
    // b) Not too late.
    //    This part is problematic in a busy test system, so we just print a warning.
    //    We already verified that a timeout occurred, we just can't be picky about how long it took.
    if (timoutException.getTimeElapsed() > maxTime(multiThreaded)) {
      System.out.println("Informative: timeout exceeded (no action required: most probably just " +
        " because the test machine is slower than usual):  " +
        "lastDoc="+exceptionDoc+
        " ,&& allowed="+timoutException.getTimeAllowed() +
        " ,&& elapsed="+timoutException.getTimeElapsed() +
        " >= " + maxTimeStr(multiThreaded));
    }
  }

  private long maxTime(boolean multiThreaded) {
    long res = 2 * counterThread.getResolution() + TIME_ALLOWED + SLOW_DOWN; // some slack for less noise in this test
    if (multiThreaded) {
      res *= MULTI_THREAD_SLACK; // larger slack
    }
    return res;
  }

  private String maxTimeStr(boolean multiThreaded) {
    String s =
      "( " +
      "2*resolution +  TIME_ALLOWED + SLOW_DOWN = " +
      "2*" + counterThread.getResolution() + " + " + TIME_ALLOWED + " + " + SLOW_DOWN +
      ")";
    if (multiThreaded) {
      s = MULTI_THREAD_SLACK + " * "+s;
    }
    return maxTime(multiThreaded) + " = " + s;
  }

  /**
   * Test timeout behavior when resolution is modified.
   */
  public void testModifyResolution() {
    try {
      // increase and test
      long resolution = 20 * TimerThread.DEFAULT_RESOLUTION; //400
      counterThread.setResolution(resolution);
      assertEquals(resolution, counterThread.getResolution());
      doTestTimeout(false,true);
      // decrease much and test
      resolution = 5;
      counterThread.setResolution(resolution);
      assertEquals(resolution, counterThread.getResolution());
      doTestTimeout(false,true);
      // return to default and test
      resolution = TimerThread.DEFAULT_RESOLUTION;
      counterThread.setResolution(resolution);
      assertEquals(resolution, counterThread.getResolution());
      doTestTimeout(false,true);
    } finally {
      counterThread.setResolution(TimerThread.DEFAULT_RESOLUTION);
    }
  }

  /**
   * Test correctness with multiple searching threads.
   */
  public void testSearchMultiThreaded() throws Exception {
    doTestMultiThreads(false);
  }

  /**
   * Test correctness with multiple searching threads.
   */
  public void testTimeoutMultiThreaded() throws Exception {
    doTestMultiThreads(true);
  }

  private void doTestMultiThreads(final boolean withTimeout) throws Exception {
    Thread [] threadArray = new Thread[N_THREADS];
    final BitSet success = new BitSet(N_THREADS);
    for( int i = 0; i < threadArray.length; ++i ) {
      final int num = i;
      threadArray[num] = new Thread() {
          @Override
          public void run() {
            if (withTimeout) {
              doTestTimeout(true,true);
            } else {
              doTestSearch();
            }
            synchronized(success) {
              success.set(num);
            }
          }
      };
    }
    for( int i = 0; i < threadArray.length; ++i ) {
      threadArray[i].start();
    }
    for( int i = 0; i < threadArray.length; ++i ) {
      threadArray[i].join();
    }
    assertEquals("some threads failed!", N_THREADS,success.cardinality());
  }

  // counting collector that can slow down at collect().
  private class MyHitCollector extends Collector {
    private final BitSet bits = new BitSet();
    private int slowdown = 0;
    private int lastDocCollected = -1;
    private int docBase = 0;

    /**
     * amount of time to wait on each collect to simulate a long iteration
     */
    public void setSlowDown( int milliseconds ) {
      slowdown = milliseconds;
    }

    public int hitCount() {
      return bits.cardinality();
    }

    public int getLastDocCollected() {
      return lastDocCollected;
    }

    @Override
    public void setScorer(Scorer scorer) throws IOException {
      // scorer is not needed
    }

    @Override
    public void collect(final int doc) throws IOException {
      int docId = doc + docBase;
      if( slowdown > 0 ) {
        try {
          Thread.sleep(slowdown);
        } catch (InterruptedException ie) {
          throw new ThreadInterruptedException(ie);
        }
      }
      assert docId >= 0: " base=" + docBase + " doc=" + doc;
      bits.set( docId );
      lastDocCollected = docId;
    }

    @Override
    public void setNextReader(AtomicReaderContext context) {
      docBase = context.docBase;
    }

    @Override
    public boolean acceptsDocsOutOfOrder() {
      return false;
    }

  }

}


text:
'use strict';

import nls = require('vs/nls');
import * as path from 'path';
import * as pfs from 'vs/base/node/pfs';
import * as errors from 'vs/base/common/errors';
import { assign } from 'vs/base/common/objects';
import { toDisposable, Disposable } from 'vs/base/common/lifecycle';
import { flatten, distinct, coalesce } from 'vs/base/common/arrays';
import { extract, buffer } from 'vs/base/node/zip';
import { TPromise } from 'vs/base/common/winjs.base';
import {
	IExtensionManagementService, IExtensionGalleryService, ILocalExtension,
	IGalleryExtension, IExtensionManifest, IGalleryMetadata,
	InstallExtensionEvent, DidInstallExtensionEvent, DidUninstallExtensionEvent, LocalExtensionType,
	StatisticType,
	IExtensionIdentifier,
	IReportedExtension
} from 'vs/platform/extensionManagement/common/extensionManagement';
import { getGalleryExtensionIdFromLocal, adoptToGalleryExtensionId, areSameExtensions, getGalleryExtensionId, groupByExtension, getMaliciousExtensionsSet, getLocalExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { localizeManifest } from '../common/extensionNls';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { Limiter } from 'vs/base/common/async';
import Event, { Emitter } from 'vs/base/common/event';
import * as semver from 'semver';
import URI from 'vs/base/common/uri';
import { IChoiceService, Severity } from 'vs/platform/message/common/message';
import pkg from 'vs/platform/node/package';
import { isMacintosh } from 'vs/base/common/platform';
import { ILogService } from 'vs/platform/log/common/log';
import { ExtensionsManifestCache } from 'vs/platform/extensionManagement/node/extensionsManifestCache';

const SystemExtensionsRoot = path.normalize(path.join(URI.parse(require.toUrl('')).fsPath, '..', 'extensions'));
const ERROR_SCANNING_SYS_EXTENSIONS = 'scanningSystem';
const ERROR_SCANNING_USER_EXTENSIONS = 'scanningUser';
const INSTALL_ERROR_UNSET_UNINSTALLED = 'unsetUninstalled';
const INSTALL_ERROR_INCOMPATIBLE = 'incompatible';
const INSTALL_ERROR_DOWNLOADING = 'downloading';
const INSTALL_ERROR_VALIDATING = 'validating';
const INSTALL_ERROR_GALLERY = 'gallery';
const INSTALL_ERROR_LOCAL = 'local';
const INSTALL_ERROR_EXTRACTING = 'extracting';
const INSTALL_ERROR_DELETING = 'deleting';
const INSTALL_ERROR_READING_EXTENSION_FROM_DISK = 'readingExtension';
const INSTALL_ERROR_SAVING_METADATA = 'savingMetadata';
const INSTALL_ERROR_UNKNOWN = 'unknown';

export class ExtensionManagementError extends Error {
	constructor(message: string, readonly code: string) {
		super(message);
	}
}

function parseManifest(raw: string): TPromise<{ manifest: IExtensionManifest; metadata: IGalleryMetadata; }> {
	return new TPromise((c, e) => {
		try {
			const manifest = JSON.parse(raw);
			const metadata = manifest.__metadata || null;
			delete manifest.__metadata;
			c({ manifest, metadata });
		} catch (err) {
			e(new Error(nls.localize('invalidManifest', "Extension invalid: package.json is not a JSON file.")));
		}
	});
}

export function validateLocalExtension(zipPath: string): TPromise<IExtensionManifest> {
	return buffer(zipPath, 'extension/package.json')
		.then(buffer => parseManifest(buffer.toString('utf8')))
		.then(({ manifest }) => TPromise.as(manifest));
}

function readManifest(extensionPath: string): TPromise<{ manifest: IExtensionManifest; metadata: IGalleryMetadata; }> {
	const promises = [
		pfs.readFile(path.join(extensionPath, 'package.json'), 'utf8')
			.then(raw => parseManifest(raw)),
		pfs.readFile(path.join(extensionPath, 'package.nls.json'), 'utf8')
			.then(null, err => err.code !== 'ENOENT' ? TPromise.wrapError<string>(err) : '{}')
			.then(raw => JSON.parse(raw))
	];

	return TPromise.join<any>(promises).then(([{ manifest, metadata }, translations]) => {
		return {
			manifest: localizeManifest(manifest, translations),
			metadata
		};
	});
}

interface InstallableExtension {
	zipPath: string;
	id: string;
	metadata?: IGalleryMetadata;
}

export class ExtensionManagementService extends Disposable implements IExtensionManagementService {

	_serviceBrand: any;

	private extensionsPath: string;
	private uninstalledPath: string;
	private uninstalledFileLimiter: Limiter<void>;
	private reportedExtensions: TPromise<IReportedExtension[]> | undefined;
	private lastReportTimestamp = 0;
	private readonly installingExtensions: Map<string, TPromise<ILocalExtension>> = new Map<string, TPromise<ILocalExtension>>();
	private readonly manifestCache: ExtensionsManifestCache;

	private readonly _onInstallExtension = new Emitter<InstallExtensionEvent>();
	readonly onInstallExtension: Event<InstallExtensionEvent> = this._onInstallExtension.event;

	private readonly _onDidInstallExtension = new Emitter<DidInstallExtensionEvent>();
	readonly onDidInstallExtension: Event<DidInstallExtensionEvent> = this._onDidInstallExtension.event;

	private readonly _onUninstallExtension = new Emitter<IExtensionIdentifier>();
	readonly onUninstallExtension: Event<IExtensionIdentifier> = this._onUninstallExtension.event;

	private _onDidUninstallExtension = new Emitter<DidUninstallExtensionEvent>();
	onDidUninstallExtension: Event<DidUninstallExtensionEvent> = this._onDidUninstallExtension.event;

	constructor(
		@IEnvironmentService environmentService: IEnvironmentService,
		@IChoiceService private choiceService: IChoiceService,
		@IExtensionGalleryService private galleryService: IExtensionGalleryService,
		@ILogService private logService: ILogService
	) {
		super();
		this.extensionsPath = environmentService.extensionsPath;
		this.uninstalledPath = path.join(this.extensionsPath, '.obsolete');
		this.uninstalledFileLimiter = new Limiter(1);
		this._register(toDisposable(() => this.installingExtensions.clear()));
		this.manifestCache = this._register(new ExtensionsManifestCache(environmentService, this));
	}

	install(zipPath: string): TPromise<void> {
		zipPath = path.resolve(zipPath);

		return validateLocalExtension(zipPath)
			.then(manifest => {
				const identifier = { id: getLocalExtensionIdFromManifest(manifest) };
				return this.unsetUninstalledAndRemove(identifier.id)
					.then(
					() => this.checkOutdated(manifest)
						.then(validated => {
							if (validated) {
								this.logService.info('Installing the extension:', identifier.id);
								this._onInstallExtension.fire({ identifier, zipPath });
								return this.getMetadata(getGalleryExtensionId(manifest.publisher, manifest.name))
									.then(
									metadata => this.installFromZipPath(identifier, zipPath, metadata, manifest),
									error => this.installFromZipPath(identifier, zipPath, null, manifest))
									.then(
									() => this.logService.info('Successfully installed the extension:', identifier.id),
									e => {
										this.logService.error('Failed to install the extension:', identifier.id, e.message);
										return TPromise.wrapError(e);
									});
							}
							return null;
						}),
					e => TPromise.wrapError(new Error(nls.localize('restartCode', "Please restart Code before reinstalling {0}.", manifest.displayName || manifest.name))));
			});
	}

	private unsetUninstalledAndRemove(id: string): TPromise<void> {
		return this.isUninstalled(id)
			.then(isUninstalled => {
				if (isUninstalled) {
					this.logService.trace('Removing the extension:', id);
					const extensionPath = path.join(this.extensionsPath, id);
					return pfs.rimraf(extensionPath)
						.then(() => this.unsetUninstalled(id))
						.then(() => this.logService.info('Removed the extension:', id));
				}
				return null;
			});
	}

	private checkOutdated(manifest: IExtensionManifest): TPromise<boolean> {
		const extensionIdentifier = { id: getGalleryExtensionId(manifest.publisher, manifest.name) };
		return this.getInstalled(LocalExtensionType.User)
			.then(installedExtensions => {
				const newer = installedExtensions.filter(local => areSameExtensions(extensionIdentifier, { id: getGalleryExtensionIdFromLocal(local) }) && semver.gt(local.manifest.version, manifest.version))[0];
				if (newer) {
					const message = nls.localize('installingOutdatedExtension', "A newer version of this extension is already installed. Would you like to override this with the older version?");
					const options = [
						nls.localize('override', "Override"),
						nls.localize('cancel', "Cancel")
					];
					return this.choiceService.choose(Severity.Info, message, options, 1, true)
						.then<boolean>(value => {
							if (value === 0) {
								return this.uninstall(newer, true).then(() => true);
							}
							return TPromise.wrapError(errors.canceled());
						});
				}
				return true;
			});
	}

	private installFromZipPath(identifier: IExtensionIdentifier, zipPath: string, metadata: IGalleryMetadata, manifest: IExtensionManifest): TPromise<void> {
		return this.installExtension({ zipPath, id: identifier.id, metadata })
			.then(local => {
				if (this.galleryService.isEnabled() && local.manifest.extensionDependencies && local.manifest.extensionDependencies.length) {
					return this.getDependenciesToInstall(local.manifest.extensionDependencies)
						.then(dependenciesToInstall => this.downloadAndInstallExtensions(metadata ? dependenciesToInstall.filter(d => d.identifier.uuid !== metadata.id) : dependenciesToInstall))
						.then(() => local, error => {
							this.uninstallExtension(local);
							return TPromise.wrapError(new Error(nls.localize('errorInstallingDependencies', "Error while installing dependencies. {0}", error instanceof Error ? error.message : error)));
						});
				}
				return local;
			})
			.then(
			local => this._onDidInstallExtension.fire({ identifier, zipPath, local }),
			error => { this._onDidInstallExtension.fire({ identifier, zipPath, error }); return TPromise.wrapError(error); }
			);
	}

	installFromGallery(extension: IGalleryExtension): TPromise<void> {
		this.onInstallExtensions([extension]);
		return this.collectExtensionsToInstall(extension)
			.then(
			extensionsToInstall => {
				if (extensionsToInstall.length > 1) {
					this.onInstallExtensions(extensionsToInstall.slice(1));
				}
				return this.downloadAndInstallExtensions(extensionsToInstall)
					.then(
					locals => this.onDidInstallExtensions(extensionsToInstall, locals, []),
					errors => this.onDidInstallExtensions(extensionsToInstall, [], errors));
			},
			error => this.onDidInstallExtensions([extension], [], [error]));
	}

	private collectExtensionsToInstall(extension: IGalleryExtension): TPromise<IGalleryExtension[]> {
		return this.galleryService.loadCompatibleVersion(extension)
			.then(compatible => {
				if (!compatible) {
					return TPromise.wrapError<IGalleryExtension[]>(new ExtensionManagementError(nls.localize('notFoundCompatible', "Unable to install '{0}'; there is no available version compatible with VS Code '{1}'.", extension.identifier.id, pkg.version), INSTALL_ERROR_INCOMPATIBLE));
				}
				return this.getDependenciesToInstall(compatible.properties.dependencies)
					.then(
					dependenciesToInstall => ([compatible, ...dependenciesToInstall.filter(d => d.identifier.uuid !== compatible.identifier.uuid)]),
					error => TPromise.wrapError<IGalleryExtension[]>(new ExtensionManagementError(this.joinErrors(error).message, INSTALL_ERROR_GALLERY)));
			},
			error => TPromise.wrapError<IGalleryExtension[]>(new ExtensionManagementError(this.joinErrors(error).message, INSTALL_ERROR_GALLERY)));
	}

	private downloadAndInstallExtensions(extensions: IGalleryExtension[]): TPromise<ILocalExtension[]> {
		return TPromise.join(extensions.map(extensionToInstall => this.downloadAndInstallExtension(extensionToInstall)))
			.then(null, errors => this.rollback(extensions).then(() => TPromise.wrapError(errors), () => TPromise.wrapError(errors)));
	}

	private downloadAndInstallExtension(extension: IGalleryExtension): TPromise<ILocalExtension> {
		let installingExtension = this.installingExtensions.get(extension.identifier.id);
		if (!installingExtension) {
			installingExtension = this.getExtensionsReport()
				.then(report => {
					if (getMaliciousExtensionsSet(report).has(extension.identifier.id)) {
						throw new Error(nls.localize('malicious extension', "Can't install extension since it was reported to be problematic."));
					} else {
						return extension;
					}
				})
				.then(extension => this.downloadInstallableExtension(extension))
				.then(installableExtension => this.installExtension(installableExtension))
				.then(
				local => { this.installingExtensions.delete(extension.identifier.id); return local; },
				e => { this.installingExtensions.delete(extension.identifier.id); return TPromise.wrapError(e); }
				);

			this.installingExtensions.set(extension.identifier.id, installingExtension);
		}
		return installingExtension;
	}

	private downloadInstallableExtension(extension: IGalleryExtension): TPromise<InstallableExtension> {
		const metadata = <IGalleryMetadata>{
			id: extension.identifier.uuid,
			publisherId: extension.publisherId,
			publisherDisplayName: extension.publisherDisplayName,
		};

		return this.galleryService.loadCompatibleVersion(extension)
			.then(
			compatible => {
				if (compatible) {
					this.logService.trace('Started downloading extension:', extension.name);
					return this.galleryService.download(extension)
						.then(
						zipPath => {
							this.logService.info('Downloaded extension:', extension.name);
							return validateLocalExtension(zipPath)
								.then(
								manifest => (<InstallableExtension>{ zipPath, id: getLocalExtensionIdFromManifest(manifest), metadata }),
								error => TPromise.wrapError(new ExtensionManagementError(this.joinErrors(error).message, INSTALL_ERROR_VALIDATING))
								);
						},
						error => TPromise.wrapError(new ExtensionManagementError(this.joinErrors(error).message, INSTALL_ERROR_DOWNLOADING)));
				} else {
					return TPromise.wrapError<InstallableExtension>(new ExtensionManagementError(nls.localize('notFoundCompatibleDependency', "Unable to install because, the depending extension '{0}' compatible with current version '{1}' of VS Code is not found.", extension.identifier.id, pkg.version), INSTALL_ERROR_INCOMPATIBLE));
				}
			},
			error => TPromise.wrapError<InstallableExtension>(new ExtensionManagementError(this.joinErrors(error).message, INSTALL_ERROR_GALLERY)));
	}

	private rollback(extensions: IGalleryExtension[]): TPromise<void> {
		return this.filterOutUninstalled(extensions)
			.then(installed => TPromise.join(installed.map(local => this.uninstallExtension(local))))
			.then(() => null, () => null);
	}

	private onInstallExtensions(extensions: IGalleryExtension[]): void {
		for (const extension of extensions) {
			this.logService.info('Installing extension:', extension.name);
			const id = getLocalExtensionIdFromGallery(extension, extension.version);
			this._onInstallExtension.fire({ identifier: { id, uuid: extension.identifier.uuid }, gallery: extension });
		}
	}

	private onDidInstallExtensions(extensions: IGalleryExtension[], locals: ILocalExtension[], errors: Error[]): TPromise<any> {
		extensions.forEach((gallery, index) => {
			const identifier = { id: getLocalExtensionIdFromGallery(gallery, gallery.version), uuid: gallery.identifier.uuid };
			const local = locals[index];
			const error = errors[index];
			if (local) {
				this.logService.info(`Extensions installed successfully:`, gallery.identifier.id);
				this._onDidInstallExtension.fire({ identifier, gallery, local });
			} else {
				const errorCode = error && (<ExtensionManagementError>error).code ? (<ExtensionManagementError>error).code : INSTALL_ERROR_UNKNOWN;
				this.logService.error(`Failed to install extension:`, gallery.identifier.id, error ? error.message : errorCode);
				this._onDidInstallExtension.fire({ identifier, gallery, error: errorCode });
			}
		});
		return errors.length ? TPromise.wrapError(this.joinErrors(errors)) : TPromise.as(null);
	}

	private getDependenciesToInstall(dependencies: string[]): TPromise<IGalleryExtension[]> {
		if (dependencies.length) {
			return this.getInstalled()
				.then(installed => {
					const uninstalledDeps = dependencies.filter(d => installed.every(i => getGalleryExtensionId(i.manifest.publisher, i.manifest.name) !== d));
					if (uninstalledDeps.length) {
						return this.galleryService.loadAllDependencies(uninstalledDeps.map(id => (<IExtensionIdentifier>{ id })))
							.then(allDependencies => allDependencies.filter(d => {
								const extensionId = getLocalExtensionIdFromGallery(d, d.version);
								return installed.every(({ identifier }) => identifier.id !== extensionId);
							}));
					}
					return [];
				});
		}
		return TPromise.as([]);
	}

	private filterOutUninstalled(extensions: IGalleryExtension[]): TPromise<ILocalExtension[]> {
		return this.getInstalled()
			.then(installed => installed.filter(local => !!this.getGalleryExtensionForLocalExtension(extensions, local)));
	}

	private getGalleryExtensionForLocalExtension(galleryExtensions: IGalleryExtension[], localExtension: ILocalExtension): IGalleryExtension {
		const filtered = galleryExtensions.filter(galleryExtension => areSameExtensions(localExtension.identifier, { id: getLocalExtensionIdFromGallery(galleryExtension, galleryExtension.version), uuid: galleryExtension.identifier.uuid }));
		return filtered.length ? filtered[0] : null;
	}

	private installExtension(installableExtension: InstallableExtension): TPromise<ILocalExtension> {
		return this.unsetUninstalledAndGetLocal(installableExtension.id)
			.then(
			local => {
				if (local) {
					return local;
				}
				return this.extractAndInstall(installableExtension);
			},
			e => {
				if (isMacintosh) {
					return TPromise.wrapError<ILocalExtension>(new ExtensionManagementError(nls.localize('quitCode', "Unable to install the extension. Please Quit and Start VS Code before reinstalling."), INSTALL_ERROR_UNSET_UNINSTALLED));
				}
				return TPromise.wrapError<ILocalExtension>(new ExtensionManagementError(nls.localize('exitCode', "Unable to install the extension. Please Exit and Start VS Code before reinstalling."), INSTALL_ERROR_UNSET_UNINSTALLED));
			});
	}

	private unsetUninstalledAndGetLocal(id: string): TPromise<ILocalExtension> {
		return this.isUninstalled(id)
			.then(isUninstalled => {
				if (isUninstalled) {
					this.logService.trace('Removing the extension from uninstalled list:', id);
					// If the same version of extension is marked as uninstalled, remove it from there and return the local.
					return this.unsetUninstalled(id)
						.then(() => {
							this.logService.info('Removed the extension from uninstalled list:', id);
							return this.getInstalled(LocalExtensionType.User);
						})
						.then(installed => installed.filter(i => i.identifier.id === id)[0]);
				}
				return null;
			});
	}

	private extractAndInstall({ zipPath, id, metadata }: InstallableExtension): TPromise<ILocalExtension> {
		const extensionPath = path.join(this.extensionsPath, id);
		return pfs.rimraf(extensionPath)
			.then(() => {
				this.logService.trace(`Started extracting the extension from ${zipPath} to ${extensionPath}`);
				return extract(zipPath, extensionPath, { sourcePath: 'extension', overwrite: true })
					.then(
					() => {
						this.logService.info(`Extracted extension to ${extensionPath}:`, id);
						return TPromise.join([readManifest(extensionPath), pfs.readdir(extensionPath)])
							.then(null, e => TPromise.wrapError(new ExtensionManagementError(this.joinErrors(e).message, INSTALL_ERROR_READING_EXTENSION_FROM_DISK)));
					},
					e => TPromise.wrapError(new ExtensionManagementError(e.message, INSTALL_ERROR_EXTRACTING)))
					.then(([{ manifest }, children]) => {
						const readme = children.filter(child => /^readme(\.txt|\.md|)$/i.test(child))[0];
						const readmeUrl = readme ? URI.file(path.join(extensionPath, readme)).toString() : null;
						const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0];
						const changelogUrl = changelog ? URI.file(path.join(extensionPath, changelog)).toString() : null;
						const type = LocalExtensionType.User;
						const identifier = { id, uuid: metadata ? metadata.id : null };

						const local: ILocalExtension = { type, identifier, manifest, metadata, path: extensionPath, readmeUrl, changelogUrl };

						this.logService.trace(`Updating metadata of the extension:`, id);
						return this.saveMetadataForLocalExtension(local)
							.then(() => {
								this.logService.info(`Updated metadata of the extension:`, id);
								return local;
							}, e => TPromise.wrapError(new ExtensionManagementError(this.joinErrors(e).message, INSTALL_ERROR_SAVING_METADATA)));
					});
			}, e => TPromise.wrapError(new ExtensionManagementError(this.joinErrors(e).message, INSTALL_ERROR_DELETING)));
	}

	uninstall(extension: ILocalExtension, force = false): TPromise<void> {
		return this.getInstalled(LocalExtensionType.User)
			.then(installed => {
				const promises = installed
					.filter(e => e.manifest.publisher === extension.manifest.publisher && e.manifest.name === extension.manifest.name)
					.map(e => this.checkForDependenciesAndUninstall(e, installed, force));
				return TPromise.join(promises).then(() => null, error => TPromise.wrapError(this.joinErrors(error)));
			});
	}

	updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata): TPromise<ILocalExtension> {
		local.metadata = metadata;
		return this.saveMetadataForLocalExtension(local)
			.then(localExtension => {
				this.manifestCache.invalidate();
				return localExtension;
			});
	}

	private saveMetadataForLocalExtension(local: ILocalExtension): TPromise<ILocalExtension> {
		if (!local.metadata) {
			return TPromise.as(local);
		}
		const manifestPath = path.join(this.extensionsPath, local.identifier.id, 'package.json');
		return pfs.readFile(manifestPath, 'utf8')
			.then(raw => parseManifest(raw))
			.then(({ manifest }) => assign(manifest, { __metadata: local.metadata }))
			.then(manifest => pfs.writeFile(manifestPath, JSON.stringify(manifest, null, '\t')))
			.then(() => local);
	}

	private getMetadata(extensionName: string): TPromise<IGalleryMetadata> {
		return this.galleryService.query({ names: [extensionName], pageSize: 1 })
			.then(galleryResult => {
				const galleryExtension = galleryResult.firstPage[0];
				return galleryExtension ? <IGalleryMetadata>{ id: galleryExtension.identifier.uuid, publisherDisplayName: galleryExtension.publisherDisplayName, publisherId: galleryExtension.publisherId } : null;
			});
	}

	private joinErrors(errorOrErrors: (Error | string) | ((Error | string)[])): Error {
		const errors = Array.isArray(errorOrErrors) ? errorOrErrors : [errorOrErrors];
		if (errors.length === 1) {
			return errors[0] instanceof Error ? <Error>errors[0] : new Error(<string>errors[0]);
		}
		return errors.reduce<Error>((previousValue: Error, currentValue: Error | string) => {
			return new Error(`${previousValue.message}${previousValue.message ? ',' : ''}${currentValue instanceof Error ? currentValue.message : currentValue}`);
		}, new Error(''));
	}

	private checkForDependenciesAndUninstall(extension: ILocalExtension, installed: ILocalExtension[], force: boolean): TPromise<void> {
		return this.preUninstallExtension(extension)
			.then(() => this.hasDependencies(extension, installed) ? this.promptForDependenciesAndUninstall(extension, installed, force) : this.promptAndUninstall(extension, installed, force))
			.then(() => this.postUninstallExtension(extension),
			error => {
				this.postUninstallExtension(extension, INSTALL_ERROR_LOCAL);
				return TPromise.wrapError(error);
			});
	}

	private hasDependencies(extension: ILocalExtension, installed: ILocalExtension[]): boolean {
		if (extension.manifest.extensionDependencies && extension.manifest.extensionDependencies.length) {
			return installed.some(i => extension.manifest.extensionDependencies.indexOf(getGalleryExtensionIdFromLocal(i)) !== -1);
		}
		return false;
	}

	private promptForDependenciesAndUninstall(extension: ILocalExtension, installed: ILocalExtension[], force: boolean): TPromise<void> {
		if (force) {
			const dependencies = distinct(this.getDependenciesToUninstallRecursively(extension, installed, [])).filter(e => e !== extension);
			return this.uninstallWithDependencies(extension, dependencies, installed);
		}

		const message = nls.localize('uninstallDependeciesConfirmation', "Would you like to uninstall '{0}' only or its dependencies also?", extension.manifest.displayName || extension.manifest.name);
		const options = [
			nls.localize('uninstallOnly', "Only"),
			nls.localize('uninstallAll', "All"),
			nls.localize('cancel', "Cancel")
		];
		this.logService.info('Requesting for confirmation to uninstall extension with dependencies', extension.identifier.id);
		return this.choiceService.choose(Severity.Info, message, options, 2, true)
			.then<void>(value => {
				if (value === 0) {
					return this.uninstallWithDependencies(extension, [], installed);
				}
				if (value === 1) {
					const dependencies = distinct(this.getDependenciesToUninstallRecursively(extension, installed, [])).filter(e => e !== extension);
					return this.uninstallWithDependencies(extension, dependencies, installed);
				}
				this.logService.info('Cancelled uninstalling extension:', extension.identifier.id);
				return TPromise.wrapError(errors.canceled());
			}, error => TPromise.wrapError(errors.canceled()));
	}

	private promptAndUninstall(extension: ILocalExtension, installed: ILocalExtension[], force: boolean): TPromise<void> {
		if (force) {
			return this.uninstallWithDependencies(extension, [], installed);
		}

		const message = nls.localize('uninstallConfirmation', "Are you sure you want to uninstall '{0}'?", extension.manifest.displayName || extension.manifest.name);
		const options = [
			nls.localize('ok', "OK"),
			nls.localize('cancel', "Cancel")
		];
		this.logService.info('Requesting for confirmation to uninstall extension', extension.identifier.id);
		return this.choiceService.choose(Severity.Info, message, options, 1, true)
			.then<void>(value => {
				if (value === 0) {
					return this.uninstallWithDependencies(extension, [], installed);
				}
				this.logService.info('Cancelled uninstalling extension:', extension.identifier.id);
				return TPromise.wrapError(errors.canceled());
			}, error => TPromise.wrapError(errors.canceled()));
	}

	private uninstallWithDependencies(extension: ILocalExtension, dependencies: ILocalExtension[], installed: ILocalExtension[]): TPromise<void> {
		const dependenciesToUninstall = this.filterDependents(extension, dependencies, installed);
		let dependents = this.getDependents(extension, installed).filter(dependent => extension !== dependent && dependenciesToUninstall.indexOf(dependent) === -1);
		if (dependents.length) {
			return TPromise.wrapError<void>(new Error(this.getDependentsErrorMessage(extension, dependents)));
		}
		return TPromise.join([this.uninstallExtension(extension), ...dependenciesToUninstall.map(d => this.doUninstall(d))]).then(() => null);
	}

	private getDependentsErrorMessage(extension: ILocalExtension, dependents: ILocalExtension[]): string {
		if (dependents.length === 1) {
			return nls.localize('singleDependentError', "Cannot uninstall extension '{0}'. Extension '{1}' depends on this.",
				extension.manifest.displayName || extension.manifest.name, dependents[0].manifest.displayName || dependents[0].manifest.name);
		}
		if (dependents.length === 2) {
			return nls.localize('twoDependentsError', "Cannot uninstall extension '{0}'. Extensions '{1}' and '{2}' depend on this.",
				extension.manifest.displayName || extension.manifest.name, dependents[0].manifest.displayName || dependents[0].manifest.name, dependents[1].manifest.displayName || dependents[1].manifest.name);
		}
		return nls.localize('multipleDependentsError', "Cannot uninstall extension '{0}'. Extensions '{1}', '{2}' and others depend on this.",
			extension.manifest.displayName || extension.manifest.name, dependents[0].manifest.displayName || dependents[0].manifest.name, dependents[1].manifest.displayName || dependents[1].manifest.name);
	}

	private getDependenciesToUninstallRecursively(extension: ILocalExtension, installed: ILocalExtension[], checked: ILocalExtension[]): ILocalExtension[] {
		if (checked.indexOf(extension) !== -1) {
			return [];
		}
		checked.push(extension);
		if (!extension.manifest.extensionDependencies || extension.manifest.extensionDependencies.length === 0) {
			return [];
		}
		const dependenciesToUninstall = installed.filter(i => extension.manifest.extensionDependencies.indexOf(getGalleryExtensionIdFromLocal(i)) !== -1);
		const depsOfDeps = [];
		for (const dep of dependenciesToUninstall) {
			depsOfDeps.push(...this.getDependenciesToUninstallRecursively(dep, installed, checked));
		}
		return [...dependenciesToUninstall, ...depsOfDeps];
	}

	private filterDependents(extension: ILocalExtension, dependencies: ILocalExtension[], installed: ILocalExtension[]): ILocalExtension[] {
		installed = installed.filter(i => i !== extension && i.manifest.extensionDependencies && i.manifest.extensionDependencies.length > 0);
		let result = dependencies.slice(0);
		for (let i = 0; i < dependencies.length; i++) {
			const dep = dependencies[i];
			const dependents = this.getDependents(dep, installed).filter(e => dependencies.indexOf(e) === -1);
			if (dependents.length) {
				result.splice(i - (dependencies.length - result.length), 1);
			}
		}
		return result;
	}

	private getDependents(extension: ILocalExtension, installed: ILocalExtension[]): ILocalExtension[] {
		return installed.filter(e => e.manifest.extensionDependencies && e.manifest.extensionDependencies.indexOf(getGalleryExtensionIdFromLocal(extension)) !== -1);
	}

	private doUninstall(extension: ILocalExtension): TPromise<void> {
		return this.preUninstallExtension(extension)
			.then(() => this.uninstallExtension(extension))
			.then(() => this.postUninstallExtension(extension),
			error => {
				this.postUninstallExtension(extension, INSTALL_ERROR_LOCAL);
				return TPromise.wrapError(error);
			});
	}

	private preUninstallExtension(extension: ILocalExtension): TPromise<void> {
		return pfs.exists(extension.path)
			.then(exists => exists ? null : TPromise.wrapError(new Error(nls.localize('notExists', "Could not find extension"))))
			.then(() => {
				this.logService.info('Uninstalling extension:', extension.identifier.id);
				this._onUninstallExtension.fire(extension.identifier);
			});
	}

	private uninstallExtension(local: ILocalExtension): TPromise<void> {
		const identifier = { id: getGalleryExtensionIdFromLocal(local), uuid: local.identifier.uuid };
		return this.scanUserExtensions(false) // Uninstall all extensions which are same as requested
			.then(extensions => extensions.filter(i => areSameExtensions({ id: getGalleryExtensionIdFromLocal(i), uuid: i.identifier.uuid }, identifier)))
			.then(uninstalled => this.setUninstalled(...uninstalled.map(u => u.identifier.id)));
	}

	private async postUninstallExtension(extension: ILocalExtension, error?: string): TPromise<void> {
		if (error) {
			this.logService.error('Failed to uninstall extension:', extension.identifier.id, error);
		} else {
			this.logService.info('Successfully uninstalled extension:', extension.identifier.id);
			// only report if extension has a mapped gallery extension. UUID identifies the gallery extension.
			if (extension.identifier.uuid) {
				await this.galleryService.reportStatistic(extension.manifest.publisher, extension.manifest.name, extension.manifest.version, StatisticType.Uninstall);
			}
		}
		this._onDidUninstallExtension.fire({ identifier: extension.identifier, error });
	}

	getInstalled(type: LocalExtensionType = null): TPromise<ILocalExtension[]> {
		const promises = [];

		if (type === null || type === LocalExtensionType.System) {
			promises.push(this.scanSystemExtensions().then(null, e => new ExtensionManagementError(this.joinErrors(e).message, ERROR_SCANNING_SYS_EXTENSIONS)));
		}

		if (type === null || type === LocalExtensionType.User) {
			promises.push(this.scanUserExtensions(true).then(null, e => new ExtensionManagementError(this.joinErrors(e).message, ERROR_SCANNING_USER_EXTENSIONS)));
		}

		return TPromise.join<ILocalExtension[]>(promises).then(flatten, errors => TPromise.wrapError<ILocalExtension[]>(this.joinErrors(errors)));
	}

	private scanSystemExtensions(): TPromise<ILocalExtension[]> {
		this.logService.trace('Started scanning system extensions');
		return this.scanExtensions(SystemExtensionsRoot, LocalExtensionType.System)
			.then(result => {
				this.logService.info('Scanned system extensions:', result.length);
				return result;
			});
	}

	private scanUserExtensions(excludeOutdated: boolean): TPromise<ILocalExtension[]> {
		this.logService.trace('Started scanning user extensions');
		return TPromise.join([this.getUninstalledExtensions(), this.scanExtensions(this.extensionsPath, LocalExtensionType.User)])
			.then(([uninstalled, extensions]) => {
				extensions = extensions.filter(e => !uninstalled[e.identifier.id]);
				if (excludeOutdated) {
					const byExtension: ILocalExtension[][] = groupByExtension(extensions, e => ({ id: getGalleryExtensionIdFromLocal(e), uuid: e.identifier.uuid }));
					extensions = byExtension.map(p => p.sort((a, b) => semver.rcompare(a.manifest.version, b.manifest.version))[0]);
				}
				this.logService.info('Scanned user extensions:', extensions.length);
				return extensions;
			});
	}

	private scanExtensions(root: string, type: LocalExtensionType): TPromise<ILocalExtension[]> {
		const limiter = new Limiter(10);
		return pfs.readdir(root)
			.then(extensionsFolders => TPromise.join(extensionsFolders.map(extensionFolder => limiter.queue(() => this.scanExtension(extensionFolder, root, type)))))
			.then(extensions => coalesce(extensions));
	}

	private scanExtension(folderName: string, root: string, type: LocalExtensionType): TPromise<ILocalExtension> {
		const extensionPath = path.join(root, folderName);
		return pfs.readdir(extensionPath)
			.then(children => readManifest(extensionPath)
				.then<ILocalExtension>(({ manifest, metadata }) => {
					const readme = children.filter(child => /^readme(\.txt|\.md|)$/i.test(child))[0];
					const readmeUrl = readme ? URI.file(path.join(extensionPath, readme)).toString() : null;
					const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0];
					const changelogUrl = changelog ? URI.file(path.join(extensionPath, changelog)).toString() : null;
					if (manifest.extensionDependencies) {
						manifest.extensionDependencies = manifest.extensionDependencies.map(id => adoptToGalleryExtensionId(id));
					}
					const identifier = { id: type === LocalExtensionType.System ? folderName : getLocalExtensionIdFromManifest(manifest), uuid: metadata ? metadata.id : null };
					return { type, identifier, manifest, metadata, path: extensionPath, readmeUrl, changelogUrl };
				}))
			.then(null, () => null);
	}

	removeDeprecatedExtensions(): TPromise<any> {
		return this.getUninstalledExtensions()
			.then(uninstalled => this.scanExtensions(this.extensionsPath, LocalExtensionType.User) // All user extensions
				.then(extensions => {
					const toRemove: { path: string, id: string }[] = [];
					// Uninstalled extensions
					toRemove.push(...extensions.filter(e => uninstalled[e.identifier.id]).map(e => ({ path: e.path, id: e.identifier.id })));

					// Outdated extensions
					const byExtension: ILocalExtension[][] = groupByExtension(extensions, e => ({ id: getGalleryExtensionIdFromLocal(e), uuid: e.identifier.uuid }));
					toRemove.push(...flatten(byExtension.map(p => p.sort((a, b) => semver.rcompare(a.manifest.version, b.manifest.version)).slice(1)))
						.map(e => ({ path: e.path, id: e.identifier.id })));

					return TPromise.join(distinct(toRemove, e => e.path).map(({ path, id }) => {
						return pfs.rimraf(path)
							.then(() => this.withUninstalledExtensions(uninstalled => delete uninstalled[id]));
					}));
				})
			);
	}

	private isUninstalled(id: string): TPromise<boolean> {
		return this.filterUninstalled(id).then(uninstalled => uninstalled.length === 1);
	}

	private filterUninstalled(...ids: string[]): TPromise<string[]> {
		return this.withUninstalledExtensions(allUninstalled => {
			const uninstalled = [];
			for (const id of ids) {
				if (!!allUninstalled[id]) {
					uninstalled.push(id);
				}
			}
			return uninstalled;
		});
	}

	private setUninstalled(...ids: string[]): TPromise<void> {
		return this.withUninstalledExtensions(uninstalled => assign(uninstalled, ids.reduce((result, id) => { result[id] = true; return result; }, {})));
	}

	private unsetUninstalled(id: string): TPromise<void> {
		return this.withUninstalledExtensions<void>(uninstalled => delete uninstalled[id]);
	}

	private getUninstalledExtensions(): TPromise<{ [id: string]: boolean; }> {
		return this.withUninstalledExtensions(uninstalled => uninstalled);
	}

	private withUninstalledExtensions<T>(fn: (uninstalled: { [id: string]: boolean; }) => T): TPromise<T> {
		return this.uninstalledFileLimiter.queue(() => {
			let result: T = null;
			return pfs.readFile(this.uninstalledPath, 'utf8')
				.then(null, err => err.code === 'ENOENT' ? TPromise.as('{}') : TPromise.wrapError(err))
				.then<{ [id: string]: boolean }>(raw => { try { return JSON.parse(raw); } catch (e) { return {}; } })
				.then(uninstalled => { result = fn(uninstalled); return uninstalled; })
				.then(uninstalled => {
					if (Object.keys(uninstalled).length === 0) {
						return pfs.rimraf(this.uninstalledPath);
					} else {
						const raw = JSON.stringify(uninstalled);
						return pfs.writeFile(this.uninstalledPath, raw);
					}
				})
				.then(() => result);
		});
	}

	getExtensionsReport(): TPromise<IReportedExtension[]> {
		const now = new Date().getTime();

		if (!this.reportedExtensions || now - this.lastReportTimestamp > 1000 * 60 * 5) { // 5 minute cache freshness
			this.reportedExtensions = this.updateReportCache();
			this.lastReportTimestamp = now;
		}

		return this.reportedExtensions;
	}

	private updateReportCache(): TPromise<IReportedExtension[]> {
		this.logService.trace('ExtensionManagementService.refreshReportedCache');

		return this.galleryService.getExtensionsReport()
			.then(result => {
				this.logService.trace(`ExtensionManagementService.refreshReportedCache - got ${result.length} reported extensions from service`);
				return result;
			}, err => {
				this.logService.trace('ExtensionManagementService.refreshReportedCache - failed to get extension report');
				return [];
			});
	}
}

export function getLocalExtensionIdFromGallery(extension: IGalleryExtension, version: string): string {
	return getLocalExtensionId(extension.identifier.id, version);
}

export function getLocalExtensionIdFromManifest(manifest: IExtensionManifest): string {
	return getLocalExtensionId(getGalleryExtensionId(manifest.publisher, manifest.name), manifest.version);
}


text:
package io.undertow.servlet.core;

import java.security.AccessController;
import java.security.PrivilegedAction;

import javax.servlet.ServletContext;

import io.undertow.server.HttpHandler;
import io.undertow.server.session.Session;
import io.undertow.servlet.handlers.ServletInitialHandler;
import io.undertow.servlet.handlers.ServletPathMatches;
import io.undertow.servlet.handlers.ServletRequestContext;
import io.undertow.servlet.spec.HttpSessionImpl;
import io.undertow.servlet.spec.ServletContextImpl;

final class SecurityActions {

    private SecurityActions() {
        // forbidden inheritance
    }

    /**
     * Gets context classloader.
     *
     * @return the current context classloader
     */
    static ClassLoader getContextClassLoader() {
        if (System.getSecurityManager() == null) {
            return Thread.currentThread().getContextClassLoader();
        } else {
            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
                public ClassLoader run() {
                    return Thread.currentThread().getContextClassLoader();
                }
            });
        }
    }

    /**
     * Sets context classloader.
     *
     * @param classLoader
     *            the classloader
     */
    static void setContextClassLoader(final ClassLoader classLoader) {
        if (System.getSecurityManager() == null) {
            Thread.currentThread().setContextClassLoader(classLoader);
        } else {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                public Object run() {
                    Thread.currentThread().setContextClassLoader(classLoader);
                    return null;
                }
            });
        }
    }
    static void setSystemProperty(final String prop, final String value) {
        if (System.getSecurityManager() == null) {
            System.setProperty(prop, value);
        } else {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                public Object run() {
                    System.setProperty(prop, value);
                    return null;
                }
            });
        }
    }

    static String getSystemProperty(final String prop) {
        if (System.getSecurityManager() == null) {
           return System.getProperty(prop);
        } else {
            return (String) AccessController.doPrivileged(new PrivilegedAction<Object>() {
                public Object run() {
                    return System.getProperty(prop);
                }
            });
        }
    }

    static HttpSessionImpl forSession(final Session session, final ServletContext servletContext, final boolean newSession) {
        if (System.getSecurityManager() == null) {
            return HttpSessionImpl.forSession(session, servletContext, newSession);
        } else {
            return AccessController.doPrivileged(new PrivilegedAction<HttpSessionImpl>() {
                @Override
                public HttpSessionImpl run() {
                    return HttpSessionImpl.forSession(session, servletContext, newSession);
                }
            });
        }
    }

    static ServletRequestContext currentServletRequestContext() {
        if (System.getSecurityManager() == null) {
            return ServletRequestContext.current();
        } else {
            return AccessController.doPrivileged(new PrivilegedAction<ServletRequestContext>() {
                @Override
                public ServletRequestContext run() {
                    return ServletRequestContext.current();
                }
            });
        }
    }

    static ServletInitialHandler createServletInitialHandler(final ServletPathMatches paths, final HttpHandler next, final CompositeThreadSetupAction setupAction, final ServletContextImpl servletContext) {
        if (System.getSecurityManager() == null) {
            return new ServletInitialHandler(paths, next, setupAction, servletContext);
        } else {
            return AccessController.doPrivileged(new PrivilegedAction<ServletInitialHandler>() {
                @Override
                public ServletInitialHandler run() {
                    return new ServletInitialHandler(paths, next, setupAction, servletContext);
                }
            });
        }
    }
}


text:
package com.empty.framework.controller;

import android.app.Activity;

import com.empty.framework.activities.IBaseActivity;
import com.empty.framework.common.FWUtil;
import com.empty.framework.controller.action.ActionResult;
import com.empty.framework.controller.action.BLExecutor;
import com.empty.framework.controller.routing.Router;
import com.empty.framework.controller.routing.RoutingTable;
import com.empty.framework.controller.validation.ValidationResult;
import com.empty.framework.controller.validation.ValidationExecutor;
import com.empty.framework.task.AsyncTasksRunner;
import com.empty.framework.task.RunnerFollower;
import com.empty.framework.task.SequentialAsyncTask;

/**
 * 一つのコントロールフローの詳細記述
 * @author id:language_and_engineering
 */
public class ControlFlowDetail<T_ActivityClass>
{
    // NOTE: T_ActivityClass -> Activityへのキャストを許可する。

    protected T_ActivityClass from_activity;
    private ValidationExecutor validation_executor;
    private BLExecutor bl_executor;
    private RoutingTable routingTable;
    protected ActionResult action_result;
	private String dialogText = "処理中です・・・";

    /**
     * 初期化
     */
    public ControlFlowDetail(T_ActivityClass fromActivity)
    {
        this.from_activity = fromActivity;
    }

    /**
     * バリデーション処理の詳細をセット
     */
    public ControlFlowDetail<T_ActivityClass> setValidation(
        ValidationExecutor validationExecutor
    )
    {
        this.validation_executor = validationExecutor;
        return this;
    }

    /**
     * BL実行の詳細をセット
     */
    public ControlFlowDetail<T_ActivityClass> setBL(
        BLExecutor blExecutor
    )
    {
        this.bl_executor = blExecutor;
        return this;
    }

    /**
     * BL実行完了時のルーティングテーブルをセット。
     * 引数によっては,画面遷移を抑止することも可能。
     */
    public ControlFlowDetail<T_ActivityClass> onBLExecuted( RoutingTable routingTable )
    {
        this.routingTable = routingTable;
        return this;
    }

    /**
     * 処理中のダイアログの文言をセット。
     * 呼び出さない場合は,デフォルトの文言が使用される。
     */
    public ControlFlowDetail<T_ActivityClass> setDialogText(String s)
    {
        this.dialogText  = s;
        return this;
    }

    /**
     * 制御フローを実行。
     * このクラスの要であり,コントローラ層の要であり,このフレームワークの要でもある重要な部分。
     */
    public void startControl()
    {
        // ActionResult格納用に
        final ControlFlowDetail<T_ActivityClass> parentFlow = this;

        // 一連の制御フローを開始
        new AsyncTasksRunner( new SequentialAsyncTask[]{

            // バリデーションを行なう非同期タスク。
            new  SequentialAsyncTask(){
                public boolean main(){
                    ValidationResult vres;

                    // バリデータがセットされていれば
                    if( validation_executor != null )
                    {
                        // Activityのparamsをバリデート
                        validation_executor.execAndStoreValidationResult();
                        vres = validation_executor.validation_result;
                    }
                    else
                    {
                        // バリデを実行しないので成功とみなす
                        vres = new ValidationResult().setSuccess();
                    }
                    storeData( "validation_result", vres );

                    // バリデの成否に応じて動作を切り替え
                    if( vres.isSuccess() )
                    {
                        FWUtil.d("バリデーションが成功しました。BL実行フェーズに進みます。");

                        // BL実行フェーズに進む
                        return CONTINUE_TASKS;
                    }
                    else
                    {
                        FWUtil.d("バリデーションが失敗しました。BLの実行はキャンセルされます。");

                        // バリデ失敗時の処理を実行
                        validation_executor.from_activity = (Activity)from_activity;
                        validation_executor.onValidationFailed();

                        // 次以降のタスクはキャンセル
                        return BREAK_TASKS;
                    }

                }
            }
            ,

            // もし可能ならBLを行なう非同期タスク。
            // DB操作やNW通信などを想定。
            new SequentialAsyncTask(){
                public boolean main(){

                    // 前のバリデーション処理の結果を取りだす
                    ValidationResult vres = (ValidationResult)getDataFromRunner("validation_result");

                    // もしバリデ結果からしてBLを実行してよいのであれば
                    if( vres.permitsExecitionOfBL() )
                    {
                        FWUtil.d("BLの実行を開始します。");

                        // BLを実行
                        bl_executor.execAndStoreActionResult();

                        // BLの結果を格納
                        storeData( "action_result", bl_executor.action_result );
                        parentFlow.action_result = bl_executor.action_result;

                        FWUtil.d("ActionResultの格納が完了しました。");
                    }

                    // BLの実行結果の是非に関らずルーティングはするので必ずtrue
                    return CONTINUE_TASKS;
                }
            }
            ,

            //  ルーティングを行なう非同期タスク
            new SequentialAsyncTask(){
                public boolean main(){

                    // ルーティングが渡されているか
                    if( routingTable != null )
                    {
                        // BLが実行された場合
                        ActionResult ares = (ActionResult)getDataFromRunner("action_result");

                        // BL実行結果に応じて遷移先を分岐
                        Router.switchByActionResult( (Activity)from_activity, ares, routingTable );
                    }
                    else
                    {
                         // ルーティングテーブルを渡さなければ,画面遷移しない。
                    }

                    return CONTINUE_TASKS;
                }
            }
        })
        .withSimpleDialog(dialogText, (Activity)from_activity) // 全非同期タスクが終了するまでダイアログを出す
        .whenAllTasksCompleted(new RunnerFollower(){
            @Override
            protected void exec() {
                ActionResult ares = parentFlow.action_result;

                // BLが実行された場合
                if( ares != null )
                {
                    // BLを非同期で実行完了後に,UIスレッド上で動く処理を実行
                    ((IBaseActivity)from_activity).afterBLExecuted(ares);

                    // NOTE: Intentで画面遷移する場合は,Intent内にActionResultが自動的に格納されるので,
                    // 遷移先の画面でUI操作処理を記述すればよい。
                    // しかし,BL実行完了に画面遷移が伴わない場合は,同一アクティビティ内でBL実行完了後に
                    // UIスレッド上でUI操作する処理を記述できる場所が必要。それがこれ。
                }
            }
        })
        .begin(); // これら全ての処理を開始

    }

}


text:
@interface SKCashTransaction ()
/// Used internally to properly restructure \c dictionaryValue
@property (nonatomic) BOOL isaRegularTransaction;
@end

@implementation SKCashTransaction

- (id)initWithDictionary:(NSDictionary *)json {
    if (json[@"iter_token"])
        return [self initWithDictionary:json[@"cash_transaction"] pagination:json[@"iter_token"]];
    return [super initWithDictionary:json];
}

- (id)initWithDictionary:(NSDictionary *)json pagination:(NSString *)pagination {
    if (!json.allKeys.count) return nil;

    // "last_cash_transaction" is flat, but normal transactions
    // contain "iter_token" and "cash_transaction"
    self = [super initWithDictionary:json];
    if (self) {
        _pagination = pagination;
    }

    return self;
}

- (NSString *)description {
    return [NSString stringWithFormat:@"<%@ sender=%@, recipient=%@, message=%@>",
            NSStringFromClass(self.class), self.sender, self.recipient, self.message];
}

#pragma mark - Mantle

+ (NSDictionary *)JSONKeyPathsByPropertyKey {
    return @{@"pagination": @"iter_token",
             @"status": @"status",
             @"amount": @"amount",
             @"currencyCode": @"currency_code",
             @"invisible": @"invisible",
             @"lastUpdated": @"last_updated_at",
             @"message": @"message",
             @"rain": @"rain",
             @"identifier": @"transaction_id",
             @"conversationIdentifier": @"conversation_id",
             @"created": @"created_at",
             @"recipient": @"recipient_username",
             @"recipientIdentifier": @"recipient_identifier",
             @"recipientSaveVersion": @"recipient_save_version",
             @"recipientSaved": @"recipient_saved",
             @"recipientViewed": @"recipient_viewed",
             @"sender": @"sender_username",
             @"senderIdentifier": @"sender_id",
             @"senderSaveVersion": @"sender_save_version",
             @"senderSaved": @"sender_saved",
             @"senderViewed": @"sender_viewed"};
}

+ (NSArray *)ignoredJSONKeyPathPrefixes {
    static NSArray *ignored = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        ignored = @[@"cash_tag_array", @"cash_tags"];
    });

    return ignored;
}

- (NSDictionary *)dictionaryValue {
    // "last_transaction" is flat and can be used normally
    if (!_isaRegularTransaction) return [super dictionaryValue];

    // Regular transactions contain 2 kv pairs:
    // "iter_token" and "cash_transaction"
    NSMutableDictionary *cash_transaction = [super dictionaryValue].mutableCopy;
    NSMutableDictionary *root = @{@"iter_token": cash_transaction[@"iter_token"]}.mutableCopy;
    cash_transaction[@"iter_token"] = nil;
    root[@"cash_transaction"] = cash_transaction.copy;
    return root.copy;
}

MTLTransformPropertyDate(lastUpdated)
MTLTransformPropertyDate(created)

#pragma mark - Equality

- (BOOL)isEqual:(id)object {
    if ([object isKindOfClass:[SKCashTransaction class]])
        return [self isEqualToTransaction:object];

    return [super isEqual:object];
}

- (BOOL)isEqualToTransaction:(SKCashTransaction *)transaction {
    return [self.identifier isEqualToString:transaction.identifier] && self.amount == transaction.amount;
}

- (NSComparisonResult)compare:(SKThing<SKPagination> *)thing {
    if ([thing respondsToSelector:@selector(created)])
        return [self.created compare:thing.created];
    return NSOrderedSame;
}

@end


text:
```
npm install -g @pastash/pastash @pastash/input_hyperbeam
```

### Example

```
input {
  hyperbeam {
    path => supersecretkeyword
  }
}

output {
  stdout {}
}
```


text:
package org.apache.sling.discovery.impl.cluster;

import java.util.Collection;

import org.apache.sling.discovery.ClusterView;
import org.apache.sling.discovery.InstanceDescription;

/**
 * The ClusterViewService is responsible and provides access to the view
 * established in a JcR cluster.
 */
public interface ClusterViewService {

    /** the sling id of the local instance **/
    String getSlingId();

    /**
     * the current cluster view
     * @return the current cluster view - never returns null
     * @throws UndefinedClusterViewException
     */
    ClusterView getClusterView() throws UndefinedClusterViewException;

    /** checks whether the cluster view contains a particular sling id **/
    boolean contains(String slingId) throws UndefinedClusterViewException;

    /** checks whether the cluster contains any of the provided instances **/
    boolean containsAny(Collection<InstanceDescription> listInstances)
            throws UndefinedClusterViewException;

}