text:
using WebKit::WebDataSource;
using WebKit::WebDocument;
using WebKit::WebFrame;
using WebKit::WebScopedUserGesture;
using WebKit::WebSecurityPolicy;
using WebKit::WebString;
using WebKit::WebVector;
using WebKit::WebView;
using content::RenderThread;
using content::RenderView;
using extensions::APIPermission;
using extensions::APIPermissionSet;
using extensions::ApiDefinitionsNatives;
using extensions::AppWindowCustomBindings;
using extensions::ContextMenusCustomBindings;
using extensions::Extension;
using extensions::ExperimentalAppCustomBindings;
using extensions::ExperimentalUsbCustomBindings;
using extensions::ExtensionAPI;
using extensions::ExtensionCustomBindings;
using extensions::Feature;
using extensions::FileBrowserHandlerCustomBindings;
using extensions::FileBrowserPrivateCustomBindings;
using extensions::FileSystemNatives;
using extensions::I18NCustomBindings;
using extensions::MiscellaneousBindings;
using extensions::MediaGalleryCustomBindings;
using extensions::PageActionsCustomBindings;
using extensions::PageCaptureCustomBindings;
using extensions::PermissionSet;
using extensions::RuntimeCustomBindings;
using extensions::SendRequestNatives;
using extensions::SetIconNatives;
using extensions::TTSCustomBindings;
using extensions::TabFinder;
using extensions::TabsCustomBindings;
using extensions::UpdatedExtensionPermissionsInfo;
using extensions::WebRequestCustomBindings;

namespace {

static const int64 kInitialExtensionIdleHandlerDelayMs = 5*1000;
static const int64 kMaxExtensionIdleHandlerDelayMs = 5*60*1000;
static const char kEventDispatchFunction[] = "Event.dispatchJSON";
static const char kOnUnloadEvent[] = "runtime.onSuspend";
static const char kOnSuspendCanceledEvent[] = "runtime.onSuspendCanceled";

class ChromeHiddenNativeHandler : public NativeHandler {
 public:
  ChromeHiddenNativeHandler() {
    RouteFunction("GetChromeHidden",
        base::Bind(&ChromeHiddenNativeHandler::GetChromeHidden,
                   base::Unretained(this)));
  }

  v8::Handle<v8::Value> GetChromeHidden(const v8::Arguments& args) {
    return ChromeV8Context::GetOrCreateChromeHidden(v8::Context::GetCurrent());
  }
};

class PrintNativeHandler : public NativeHandler {
 public:
  PrintNativeHandler() {
    RouteFunction("Print",
        base::Bind(&PrintNativeHandler::Print,
                   base::Unretained(this)));
  }

  v8::Handle<v8::Value> Print(const v8::Arguments& args) {
    if (args.Length() < 1)
      return v8::Undefined();

    std::vector<std::string> components;
    for (int i = 0; i < args.Length(); ++i)
      components.push_back(*v8::String::Utf8Value(args[i]->ToString()));

    LOG(ERROR) << JoinString(components, ',');
    return v8::Undefined();
  }
};

class LazyBackgroundPageNativeHandler : public ChromeV8Extension {
 public:
  explicit LazyBackgroundPageNativeHandler(ExtensionDispatcher* dispatcher)
      : ChromeV8Extension(dispatcher) {
    RouteFunction("IncrementKeepaliveCount",
        base::Bind(&LazyBackgroundPageNativeHandler::IncrementKeepaliveCount,
                   base::Unretained(this)));
    RouteFunction("DecrementKeepaliveCount",
        base::Bind(&LazyBackgroundPageNativeHandler::DecrementKeepaliveCount,
                   base::Unretained(this)));
  }

  v8::Handle<v8::Value> IncrementKeepaliveCount(const v8::Arguments& args) {
    ChromeV8Context* context =
        extension_dispatcher()->v8_context_set().GetCurrent();
    if (!context)
      return v8::Undefined();
    RenderView* render_view = context->GetRenderView();
    if (IsContextLazyBackgroundPage(render_view, context->extension())) {
      render_view->Send(new ExtensionHostMsg_IncrementLazyKeepaliveCount(
          render_view->GetRoutingID()));
    }
    return v8::Undefined();
  }

  v8::Handle<v8::Value> DecrementKeepaliveCount(const v8::Arguments& args) {
    ChromeV8Context* context =
        extension_dispatcher()->v8_context_set().GetCurrent();
    if (!context)
      return v8::Undefined();
    RenderView* render_view = context->GetRenderView();
    if (IsContextLazyBackgroundPage(render_view, context->extension())) {
      render_view->Send(new ExtensionHostMsg_DecrementLazyKeepaliveCount(
          render_view->GetRoutingID()));
    }
    return v8::Undefined();
  }

 private:
  bool IsContextLazyBackgroundPage(RenderView* render_view,
                                   const Extension* extension) {
    if (!render_view)
      return false;

    ExtensionHelper* helper = ExtensionHelper::Get(render_view);
    return (extension && extension->has_lazy_background_page() &&
            helper->view_type() == chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE);
  }
};

class ProcessInfoNativeHandler : public ChromeV8Extension {
 public:
  explicit ProcessInfoNativeHandler(
      ExtensionDispatcher* dispatcher,
      const std::string& extension_id,
      const std::string& context_type,
      bool is_incognito_context,
      int manifest_version)
      : ChromeV8Extension(dispatcher),
        extension_id_(extension_id),
        context_type_(context_type),
        is_incognito_context_(is_incognito_context),
        manifest_version_(manifest_version) {
    RouteFunction("GetExtensionId",
        base::Bind(&ProcessInfoNativeHandler::GetExtensionId,
                   base::Unretained(this)));
    RouteFunction("GetContextType",
        base::Bind(&ProcessInfoNativeHandler::GetContextType,
                   base::Unretained(this)));
    RouteFunction("InIncognitoContext",
        base::Bind(&ProcessInfoNativeHandler::InIncognitoContext,
                   base::Unretained(this)));
    RouteFunction("GetManifestVersion",
        base::Bind(&ProcessInfoNativeHandler::GetManifestVersion,
                   base::Unretained(this)));
  }

  v8::Handle<v8::Value> GetExtensionId(const v8::Arguments& args) {
    return v8::String::New(extension_id_.c_str());
  }

  v8::Handle<v8::Value> GetContextType(const v8::Arguments& args) {
    return v8::String::New(context_type_.c_str());
  }

  v8::Handle<v8::Value> InIncognitoContext(const v8::Arguments& args) {
    return v8::Boolean::New(is_incognito_context_);
  }

  v8::Handle<v8::Value> GetManifestVersion(const v8::Arguments& args) {
    return v8::Integer::New(manifest_version_);
  }

 private:
  std::string extension_id_;
  std::string context_type_;
  bool is_incognito_context_;
  int manifest_version_;
};

class ChannelNativeHandler : public NativeHandler {
 public:
  explicit ChannelNativeHandler(chrome::VersionInfo::Channel channel)
      : channel_(channel) {
    RouteFunction("IsDevChannel",
        base::Bind(&ChannelNativeHandler::IsDevChannel,
                   base::Unretained(this)));
  }

  v8::Handle<v8::Value> IsDevChannel(const v8::Arguments& args) {
    return v8::Boolean::New(channel_ <= chrome::VersionInfo::CHANNEL_DEV);
  }

  chrome::VersionInfo::Channel channel_;
};

class LoggingNativeHandler : public NativeHandler {
 public:
  LoggingNativeHandler() {
    RouteFunction("DCHECK",
        base::Bind(&LoggingNativeHandler::Dcheck,
                   base::Unretained(this)));
  }

  v8::Handle<v8::Value> Dcheck(const v8::Arguments& args) {
    CHECK_LE(args.Length(), 2);
    bool check_value = args[0]->BooleanValue();
    std::string error_message;
    if (args.Length() == 2)
      error_message += "Error: " + std::string(*v8::String::AsciiValue(args[1]))
          + "\n";

    v8::Handle<v8::Array> stack_trace(
        v8::StackTrace::CurrentStackTrace(10)->AsArray());
    error_message += "Stack trace: {\n";
    for (size_t i = 0; i < stack_trace->Length(); i++) {
      error_message += "  "
          + std::string(*v8::String::AsciiValue(stack_trace->Get(i))) + "\n";
    }
    error_message += "}";
    DCHECK(check_value) << error_message;
    return v8::Undefined();
  }
};

void InstallAppBindings(ModuleSystem* module_system,
                        v8::Handle<v8::Object> chrome,
                        v8::Handle<v8::Object> chrome_hidden) {
  module_system->SetLazyField(chrome, "app", "app", "chromeApp");
  module_system->SetLazyField(chrome, "appNotifications", "app",
                              "chromeAppNotifications");
  module_system->SetLazyField(chrome_hidden, "app", "app",
                              "chromeHiddenApp");
}

void InstallWebstoreBindings(ModuleSystem* module_system,
                             v8::Handle<v8::Object> chrome,
                             v8::Handle<v8::Object> chrome_hidden) {
  module_system->SetLazyField(chrome, "webstore", "webstore", "chromeWebstore");
  module_system->SetLazyField(chrome_hidden, "webstore", "webstore",
                              "chromeHiddenWebstore");
}

static v8::Handle<v8::Object> GetOrCreateChrome(
    v8::Handle<v8::Context> context) {
  v8::Handle<v8::String> chrome_string(v8::String::New("chrome"));
  v8::Handle<v8::Object> global(context->Global());
  v8::Handle<v8::Value> chrome(global->Get(chrome_string));
  if (chrome.IsEmpty() || chrome->IsUndefined()) {
    v8::Handle<v8::Object> chrome_object(v8::Object::New());
    global->Set(chrome_string, chrome_object);
    return chrome_object;
  }
  CHECK(chrome->IsObject());
  return chrome->ToObject();
}

}  // namespace

ExtensionDispatcher::ExtensionDispatcher()
    : is_webkit_initialized_(false),
      webrequest_adblock_(false),
      webrequest_adblock_plus_(false),
      webrequest_other_(false),
      source_map_(&ResourceBundle::GetSharedInstance()),
      chrome_channel_(chrome::VersionInfo::CHANNEL_UNKNOWN) {
  const CommandLine& command_line = *(CommandLine::ForCurrentProcess());
  is_extension_process_ =
      command_line.HasSwitch(switches::kExtensionProcess) ||
      command_line.HasSwitch(switches::kSingleProcess);

  if (is_extension_process_) {
    RenderThread::Get()->SetIdleNotificationDelayInMs(
        kInitialExtensionIdleHandlerDelayMs);
  }

  user_script_slave_.reset(new extensions::UserScriptSlave(&extensions_));
  request_sender_.reset(new ExtensionRequestSender(this, &v8_context_set_));
  PopulateSourceMap();
  PopulateLazyBindingsMap();
}

ExtensionDispatcher::~ExtensionDispatcher() {
}

bool ExtensionDispatcher::OnControlMessageReceived(
    const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(ExtensionDispatcher, message)
    IPC_MESSAGE_HANDLER(ExtensionMsg_SetChannel, OnSetChannel)
    IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnMessageInvoke)
    IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnConnect, OnDispatchOnConnect)
    IPC_MESSAGE_HANDLER(ExtensionMsg_DeliverMessage, OnDeliverMessage)
    IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnDisconnect,
                        OnDispatchOnDisconnect)
    IPC_MESSAGE_HANDLER(ExtensionMsg_SetFunctionNames, OnSetFunctionNames)
    IPC_MESSAGE_HANDLER(ExtensionMsg_Loaded, OnLoaded)
    IPC_MESSAGE_HANDLER(ExtensionMsg_Unloaded, OnUnloaded)
    IPC_MESSAGE_HANDLER(ExtensionMsg_SetScriptingWhitelist,
                        OnSetScriptingWhitelist)
    IPC_MESSAGE_HANDLER(ExtensionMsg_ActivateExtension, OnActivateExtension)
    IPC_MESSAGE_HANDLER(ExtensionMsg_UpdatePermissions, OnUpdatePermissions)
    IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateTabSpecificPermissions,
                        OnUpdateTabSpecificPermissions)
    IPC_MESSAGE_HANDLER(ExtensionMsg_ClearTabSpecificPermissions,
                        OnClearTabSpecificPermissions)
    IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateUserScripts, OnUpdateUserScripts)
    IPC_MESSAGE_HANDLER(ExtensionMsg_UsingWebRequestAPI, OnUsingWebRequestAPI)
    IPC_MESSAGE_HANDLER(ExtensionMsg_ShouldUnload, OnShouldUnload)
    IPC_MESSAGE_HANDLER(ExtensionMsg_Unload, OnUnload)
    IPC_MESSAGE_HANDLER(ExtensionMsg_CancelUnload, OnCancelUnload)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()

  return handled;
}

void ExtensionDispatcher::WebKitInitialized() {
  // For extensions, we want to ensure we call the IdleHandler every so often,
  // even if the extension keeps up activity.
  if (is_extension_process_) {
    forced_idle_timer_.Start(FROM_HERE,
        base::TimeDelta::FromMilliseconds(kMaxExtensionIdleHandlerDelayMs),
        RenderThread::Get(), &RenderThread::IdleHandler);
  }

  // Initialize host permissions for any extensions that were activated before
  // WebKit was initialized.
  for (std::set<std::string>::iterator iter = active_extension_ids_.begin();
       iter != active_extension_ids_.end(); ++iter) {
    const Extension* extension = extensions_.GetByID(*iter);
    CHECK(extension);
    InitOriginPermissions(extension);
  }

  is_webkit_initialized_ = true;
}

void ExtensionDispatcher::IdleNotification() {
  if (is_extension_process_) {
    // Dampen the forced delay as well if the extension stays idle for long
    // periods of time.
    int64 forced_delay_ms = std::max(
        RenderThread::Get()->GetIdleNotificationDelayInMs(),
        kMaxExtensionIdleHandlerDelayMs);
    forced_idle_timer_.Stop();
    forced_idle_timer_.Start(FROM_HERE,
        base::TimeDelta::FromMilliseconds(forced_delay_ms),
        RenderThread::Get(), &RenderThread::IdleHandler);
  }
}

void ExtensionDispatcher::OnSetFunctionNames(
    const std::vector<std::string>& names) {
  function_names_.clear();
  for (size_t i = 0; i < names.size(); ++i)
    function_names_.insert(names[i]);
}

void ExtensionDispatcher::OnSetChannel(int channel) {
  chrome_channel_ = channel;
}

void ExtensionDispatcher::OnMessageInvoke(const std::string& extension_id,
                                          const std::string& function_name,
                                          const ListValue& args,
                                          const GURL& event_url,
                                          bool user_gesture) {
  scoped_ptr<WebScopedUserGesture> web_user_gesture;
  if (user_gesture) {
    web_user_gesture.reset(new WebScopedUserGesture);
  }

  v8_context_set_.DispatchChromeHiddenMethod(
      extension_id, function_name, args, NULL, event_url);

  // Reset the idle handler each time there's any activity like event or message
  // dispatch, for which Invoke is the chokepoint.
  if (is_extension_process_) {
    RenderThread::Get()->ScheduleIdleHandler(
        kInitialExtensionIdleHandlerDelayMs);
  }

  // Tell the browser process when an event has been dispatched with a lazy
  // background page active.
  const Extension* extension = extensions_.GetByID(extension_id);
  if (extension && extension->has_lazy_background_page() &&
      function_name == kEventDispatchFunction) {
    RenderView* background_view =
        ExtensionHelper::GetBackgroundPage(extension_id);
    if (background_view) {
      background_view->Send(new ExtensionHostMsg_EventAck(
          background_view->GetRoutingID()));
    }
  }
}

void ExtensionDispatcher::OnDispatchOnConnect(
    int target_port_id,
    const std::string& channel_name,
    const std::string& tab_json,
    const std::string& source_extension_id,
    const std::string& target_extension_id) {
  MiscellaneousBindings::DispatchOnConnect(
      v8_context_set_.GetAll(),
      target_port_id, channel_name, tab_json,
      source_extension_id, target_extension_id,
      NULL);  // All render views.
}

void ExtensionDispatcher::OnDeliverMessage(int target_port_id,
                                           const std::string& message) {
  MiscellaneousBindings::DeliverMessage(
      v8_context_set_.GetAll(),
      target_port_id,
      message,
      NULL);  // All render views.
}

void ExtensionDispatcher::OnDispatchOnDisconnect(int port_id,
                                                bool connection_error) {
  MiscellaneousBindings::DispatchOnDisconnect(
      v8_context_set_.GetAll(),
      port_id, connection_error,
      NULL);  // All render views.
}

void ExtensionDispatcher::OnLoaded(
    const std::vector<ExtensionMsg_Loaded_Params>& loaded_extensions) {
  std::vector<WebString> platform_app_patterns;

  std::vector<ExtensionMsg_Loaded_Params>::const_iterator i;
  for (i = loaded_extensions.begin(); i != loaded_extensions.end(); ++i) {
    scoped_refptr<const Extension> extension(i->ConvertToExtension());
    if (!extension) {
      // This can happen if extension parsing fails for any reason. One reason
      // this can legitimately happen is if the
      // --enable-experimental-extension-apis changes at runtime, which happens
      // during browser tests. Existing renderers won't know about the change.
      continue;
    }

    extensions_.Insert(extension);

    if (extension->is_platform_app()) {
      platform_app_patterns.push_back(
          WebString::fromUTF8(extension->url().spec() + "*"));
    }
  }

  if (!platform_app_patterns.empty()) {
    // We have collected a set of platform-app extensions, so let's tell WebKit
    // about them so that it can provide a default stylesheet for them.
    //
    // TODO(miket): consider enhancing WebView to allow removing
    // single stylesheets, or else to edit the pattern set associated
    // with one.
    WebVector<WebString> patterns;
    patterns.assign(platform_app_patterns);
    WebView::addUserStyleSheet(
        WebString::fromUTF8(ResourceBundle::GetSharedInstance().
            GetRawDataResource(IDR_PLATFORM_APP_CSS,
                               ui::SCALE_FACTOR_NONE)),
        patterns,
        WebView::UserContentInjectInAllFrames,
        WebView::UserStyleInjectInExistingDocuments);
  }
}

void ExtensionDispatcher::OnUnloaded(const std::string& id) {
  extensions_.Remove(id);
  active_extension_ids_.erase(id);

  // If the extension is later reloaded with a different set of permissions,
  // we'd like it to get a new isolated world ID, so that it can pick up the
  // changed origin whitelist.
  user_script_slave_->RemoveIsolatedWorld(id);

  // We don't do anything with existing platform-app stylesheets. They will
  // stay resident, but the URL pattern corresponding to the unloaded
  // extension's URL just won't match anything anymore.
}

void ExtensionDispatcher::OnSetScriptingWhitelist(
    const Extension::ScriptingWhitelist& extension_ids) {
  Extension::SetScriptingWhitelist(extension_ids);
}

bool ExtensionDispatcher::IsExtensionActive(
    const std::string& extension_id) const {
  bool is_active =
      active_extension_ids_.find(extension_id) != active_extension_ids_.end();
  if (is_active)
    CHECK(extensions_.Contains(extension_id));
  return is_active;
}

bool ExtensionDispatcher::AllowScriptExtension(
    WebFrame* frame,
    const std::string& v8_extension_name,
    int extension_group) {
  return AllowScriptExtension(frame, v8_extension_name, extension_group, 0);
}

namespace {

// This is what the extension_group variable will be when DidCreateScriptContext
// is called. We know because it's the same as what AllowScriptExtension gets
// passed, and the two functions are called sequentially from WebKit.
//
// TODO(koz): Plumb extension_group through to AllowScriptExtension() from
// WebKit.
static int g_hack_extension_group = 0;

}

bool ExtensionDispatcher::AllowScriptExtension(
    WebFrame* frame,
    const std::string& v8_extension_name,
    int extension_group,
    int world_id) {
  g_hack_extension_group = extension_group;
  return true;
}

void ExtensionDispatcher::RegisterNativeHandlers(ModuleSystem* module_system,
                                                 ChromeV8Context* context) {
  module_system->RegisterNativeHandler("event_bindings",
      scoped_ptr<NativeHandler>(EventBindings::Get(this)));
  module_system->RegisterNativeHandler("miscellaneous_bindings",
      scoped_ptr<NativeHandler>(MiscellaneousBindings::Get(this)));
  module_system->RegisterNativeHandler("apiDefinitions",
      scoped_ptr<NativeHandler>(new ApiDefinitionsNatives(this)));
  module_system->RegisterNativeHandler("sendRequest",
      scoped_ptr<NativeHandler>(
          new SendRequestNatives(this, request_sender_.get())));
  module_system->RegisterNativeHandler("setIcon",
      scoped_ptr<NativeHandler>(
          new SetIconNatives(this, request_sender_.get())));

  // Natives used by multiple APIs.
  module_system->RegisterNativeHandler("file_system_natives",
      scoped_ptr<NativeHandler>(new FileSystemNatives()));

  // Custom bindings.
  module_system->RegisterNativeHandler("app",
      scoped_ptr<NativeHandler>(new AppBindings(this, context)));
  module_system->RegisterNativeHandler("app_window",
      scoped_ptr<NativeHandler>(new AppWindowCustomBindings(this)));
  module_system->RegisterNativeHandler("context_menus",
      scoped_ptr<NativeHandler>(new ContextMenusCustomBindings()));
  module_system->RegisterNativeHandler("extension",
      scoped_ptr<NativeHandler>(
          new ExtensionCustomBindings(this)));
  module_system->RegisterNativeHandler("experimental_app",
      scoped_ptr<NativeHandler>(new ExperimentalAppCustomBindings()));
  module_system->RegisterNativeHandler("experimental_mediaGalleries",
      scoped_ptr<NativeHandler>(new MediaGalleryCustomBindings()));
  module_system->RegisterNativeHandler("experimental_usb",
      scoped_ptr<NativeHandler>(new ExperimentalUsbCustomBindings()));
  module_system->RegisterNativeHandler("file_browser_handler",
      scoped_ptr<NativeHandler>(new FileBrowserHandlerCustomBindings()));
  module_system->RegisterNativeHandler("file_browser_private",
      scoped_ptr<NativeHandler>(new FileBrowserPrivateCustomBindings()));
  module_system->RegisterNativeHandler("i18n",
      scoped_ptr<NativeHandler>(new I18NCustomBindings()));
  module_system->RegisterNativeHandler("page_actions",
      scoped_ptr<NativeHandler>(
          new PageActionsCustomBindings(this)));
  module_system->RegisterNativeHandler("page_capture",
      scoped_ptr<NativeHandler>(new PageCaptureCustomBindings()));
  module_system->RegisterNativeHandler("runtime",
      scoped_ptr<NativeHandler>(new RuntimeCustomBindings(context)));
  module_system->RegisterNativeHandler("tabs",
      scoped_ptr<NativeHandler>(new TabsCustomBindings()));
  module_system->RegisterNativeHandler("tts",
      scoped_ptr<NativeHandler>(new TTSCustomBindings()));
  module_system->RegisterNativeHandler("web_request",
      scoped_ptr<NativeHandler>(new WebRequestCustomBindings()));
  module_system->RegisterNativeHandler("webstore",
      scoped_ptr<NativeHandler>(new WebstoreBindings(this, context)));
}

void ExtensionDispatcher::PopulateSourceMap() {
  source_map_.RegisterSource("event_bindings", IDR_EVENT_BINDINGS_JS);
  source_map_.RegisterSource("miscellaneous_bindings",
      IDR_MISCELLANEOUS_BINDINGS_JS);
  source_map_.RegisterSource("schema_generated_bindings",
      IDR_SCHEMA_GENERATED_BINDINGS_JS);
  source_map_.RegisterSource("json_schema", IDR_JSON_SCHEMA_JS);
  source_map_.RegisterSource("apitest", IDR_EXTENSION_APITEST_JS);

  // Libraries.
  source_map_.RegisterSource("lastError", IDR_LAST_ERROR_JS);
  source_map_.RegisterSource("schemaUtils", IDR_SCHEMA_UTILS_JS);
  source_map_.RegisterSource("sendRequest", IDR_SEND_REQUEST_JS);
  source_map_.RegisterSource("setIcon", IDR_SET_ICON_JS);
  source_map_.RegisterSource("utils", IDR_UTILS_JS);

  // Custom bindings.
  source_map_.RegisterSource("app", IDR_APP_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("app.window", IDR_APP_WINDOW_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("browserAction",
                             IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("contentSettings",
                             IDR_CONTENT_SETTINGS_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("contextMenus",
                             IDR_CONTEXT_MENUS_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("declarativeWebRequest",
                             IDR_DECLARATIVE_WEBREQUEST_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("devtools", IDR_DEVTOOLS_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("experimental.app",
                             IDR_EXPERIMENTAL_APP_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("experimental.bluetooth",
                             IDR_EXPERIMENTAL_BLUETOOTH_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("experimental.mediaGalleries",
                             IDR_EXPERIMENTAL_MEDIA_GALLERY_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("experimental.offscreen",
                             IDR_EXPERIMENTAL_OFFSCREENTABS_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("experimental.usb",
                             IDR_EXPERIMENTAL_USB_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("extension", IDR_EXTENSION_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("fileBrowserHandler",
                             IDR_FILE_BROWSER_HANDLER_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("fileBrowserPrivate",
                             IDR_FILE_BROWSER_PRIVATE_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("fileSystem",
                             IDR_FILE_SYSTEM_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("i18n", IDR_I18N_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("input.ime", IDR_INPUT_IME_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("omnibox", IDR_OMNIBOX_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("pageActions",
                             IDR_PAGE_ACTIONS_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("pageAction", IDR_PAGE_ACTION_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("pageCapture",
                             IDR_PAGE_CAPTURE_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("runtime", IDR_RUNTIME_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("storage", IDR_STORAGE_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("tabs", IDR_TABS_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("tts", IDR_TTS_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("ttsEngine", IDR_TTS_ENGINE_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("types", IDR_TYPES_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("webRequest", IDR_WEB_REQUEST_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("webRequestInternal",
                             IDR_WEB_REQUEST_INTERNAL_CUSTOM_BINDINGS_JS);
  source_map_.RegisterSource("webstore", IDR_WEBSTORE_CUSTOM_BINDINGS_JS);

  // Platform app sources that are not API-specific..
  source_map_.RegisterSource("browserTag", IDR_BROWSER_TAG_JS);
  source_map_.RegisterSource("platformApp", IDR_PLATFORM_APP_JS);
}

void ExtensionDispatcher::PopulateLazyBindingsMap() {
  lazy_bindings_map_["app"] = InstallAppBindings;
  lazy_bindings_map_["webstore"] = InstallWebstoreBindings;
}

void ExtensionDispatcher::InstallBindings(ModuleSystem* module_system,
                                          v8::Handle<v8::Context> v8_context,
                                          const std::string& api) {
  std::map<std::string, BindingInstaller>::const_iterator lazy_binding =
      lazy_bindings_map_.find(api);
  if (lazy_binding != lazy_bindings_map_.end()) {
    v8::Handle<v8::Object> global(v8_context->Global());
    v8::Handle<v8::Object> chrome =
        global->Get(v8::String::New("chrome"))->ToObject();
    v8::Handle<v8::Object> chrome_hidden =
        ChromeV8Context::GetOrCreateChromeHidden(v8_context)->ToObject();
    (*lazy_binding->second)(module_system, chrome, chrome_hidden);
  } else {
    module_system->Require(api);
  }
}

void ExtensionDispatcher::DidCreateScriptContext(
    WebFrame* frame, v8::Handle<v8::Context> v8_context, int extension_group,
    int world_id) {
  // TODO(koz): If the caller didn't pass extension_group, use the last value.
  if (extension_group == -1)
    extension_group = g_hack_extension_group;

  std::string extension_id = GetExtensionID(frame, world_id);

  const Extension* extension = extensions_.GetByID(extension_id);
  if (!extension && !extension_id.empty()) {
    // There are conditions where despite a context being associated with an
    // extension, no extension actually gets found.  Ignore "invalid" because
    // CSP blocks extension page loading by switching the extension ID to
    // "invalid". This isn't interesting.
    if (extension_id != "invalid") {
      LOG(ERROR) << "Extension \"" << extension_id << "\" not found";
      RenderThread::Get()->RecordUserMetrics("ExtensionNotFound_ED");
    }

    extension_id = "";
  }

  ExtensionURLInfo url_info(frame->document().securityOrigin(),
      extensions::UserScriptSlave::GetDataSourceURLForFrame(frame));

  Feature::Context context_type =
      ClassifyJavaScriptContext(extension_id, extension_group, url_info);

  ChromeV8Context* context =
      new ChromeV8Context(v8_context, frame, extension, context_type);
  v8_context_set_.Add(context);

  scoped_ptr<ModuleSystem> module_system(new ModuleSystem(v8_context,
                                                          &source_map_));
  // Enable natives in startup.
  ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system.get());

  RegisterNativeHandlers(module_system.get(), context);

  module_system->RegisterNativeHandler("chrome_hidden",
      scoped_ptr<NativeHandler>(new ChromeHiddenNativeHandler()));
  module_system->RegisterNativeHandler("print",
      scoped_ptr<NativeHandler>(new PrintNativeHandler()));
  module_system->RegisterNativeHandler("lazy_background_page",
      scoped_ptr<NativeHandler>(new LazyBackgroundPageNativeHandler(this)));
  module_system->RegisterNativeHandler("channel",
      scoped_ptr<NativeHandler>(new ChannelNativeHandler(
          static_cast<chrome::VersionInfo::Channel>(chrome_channel_))));
  module_system->RegisterNativeHandler("logging",
      scoped_ptr<NativeHandler>(new LoggingNativeHandler()));

  int manifest_version = extension ? extension->manifest_version() : 1;
  module_system->RegisterNativeHandler("process",
      scoped_ptr<NativeHandler>(new ProcessInfoNativeHandler(
          this, context->GetExtensionID(),
          context->GetContextTypeDescription(),
          ChromeRenderProcessObserver::is_incognito_process(),
          manifest_version)));

  GetOrCreateChrome(v8_context);

  // Loading JavaScript is expensive, so only run the full API bindings
  // generation mechanisms in extension pages (NOT all web pages).
  switch (context_type) {
    case Feature::UNSPECIFIED_CONTEXT:
    case Feature::WEB_PAGE_CONTEXT:
      // TODO(kalman): see comment below about ExtensionAPI.
      InstallBindings(module_system.get(), v8_context, "app");
      InstallBindings(module_system.get(), v8_context, "webstore");
      break;

    case Feature::BLESSED_EXTENSION_CONTEXT:
    case Feature::UNBLESSED_EXTENSION_CONTEXT:
    case Feature::CONTENT_SCRIPT_CONTEXT: {
      CHECK(extension);
      if (!extension->is_platform_app())
        module_system->Require("miscellaneous_bindings");
      module_system->Require("schema_generated_bindings");
      module_system->Require("apitest");

      // TODO(kalman): move this code back out of the switch and execute it
      // regardless of |context_type|. ExtensionAPI knows how to return the
      // correct APIs, however, until it doesn't have a 2MB overhead we can't
      // load it in every process.
      const std::set<std::string>& apis = context->GetAvailableExtensionAPIs();
      for (std::set<std::string>::const_iterator i = apis.begin();
           i != apis.end(); ++i) {
        InstallBindings(module_system.get(), v8_context, *i);
      }

      break;
    }
  }

  // Inject custom JS into the platform app context.
  if (IsWithinPlatformApp(frame))
    module_system->Require("platformApp");

  if (context_type == Feature::BLESSED_EXTENSION_CONTEXT &&
      extension->HasAPIPermission(APIPermission::kBrowserTag)) {
    module_system->Require("browserTag");
  }

  context->set_module_system(module_system.Pass());

  context->DispatchOnLoadEvent(
      ChromeRenderProcessObserver::is_incognito_process(),
      manifest_version);

  VLOG(1) << "Num tracked contexts: " << v8_context_set_.size();
}

std::string ExtensionDispatcher::GetExtensionID(const WebFrame* frame,
                                                int world_id) {
  if (world_id != 0) {
    // Isolated worlds (content script).
    return user_script_slave_->GetExtensionIdForIsolatedWorld(world_id);
  }

  // Extension pages (chrome-extension:// URLs).
  GURL frame_url = extensions::UserScriptSlave::GetDataSourceURLForFrame(frame);
  return extensions_.GetExtensionOrAppIDByURL(
      ExtensionURLInfo(frame->document().securityOrigin(), frame_url));
}

bool ExtensionDispatcher::IsWithinPlatformApp(const WebFrame* frame) {
  const Extension* extension =
      extensions_.GetByID(GetExtensionID(frame->top(), 0));
  return extension && extension->is_platform_app();
}

void ExtensionDispatcher::WillReleaseScriptContext(
    WebFrame* frame, v8::Handle<v8::Context> v8_context, int world_id) {
  ChromeV8Context* context = v8_context_set_.GetByV8Context(v8_context);
  if (!context)
    return;

  context->DispatchOnUnloadEvent();

  v8_context_set_.Remove(context);
  VLOG(1) << "Num tracked contexts: " << v8_context_set_.size();
}

void ExtensionDispatcher::OnActivateExtension(
    const std::string& extension_id) {
  active_extension_ids_.insert(extension_id);
  const Extension* extension = extensions_.GetByID(extension_id);
  CHECK(extension);

  // This is called when starting a new extension page, so start the idle
  // handler ticking.
  RenderThread::Get()->ScheduleIdleHandler(kInitialExtensionIdleHandlerDelayMs);

  UpdateActiveExtensions();

  if (is_webkit_initialized_)
    InitOriginPermissions(extension);
}

void ExtensionDispatcher::InitOriginPermissions(const Extension* extension) {
  // TODO(jstritar): We should try to remove this special case. Also, these
  // whitelist entries need to be updated when the kManagement permission
  // changes.
  if (extension->HasAPIPermission(APIPermission::kManagement)) {
    WebSecurityPolicy::addOriginAccessWhitelistEntry(
        extension->url(),
        WebString::fromUTF8(chrome::kChromeUIScheme),
        WebString::fromUTF8(chrome::kChromeUIExtensionIconHost),
        false);
  }

  AddOrRemoveOriginPermissions(
      UpdatedExtensionPermissionsInfo::ADDED,
      extension,
      extension->GetActivePermissions()->explicit_hosts());
}

void ExtensionDispatcher::AddOrRemoveOriginPermissions(
    UpdatedExtensionPermissionsInfo::Reason reason,
    const Extension* extension,
    const URLPatternSet& origins) {
  for (URLPatternSet::const_iterator i = origins.begin();
       i != origins.end(); ++i) {
    const char* schemes[] = {
      chrome::kHttpScheme,
      chrome::kHttpsScheme,
      chrome::kFileScheme,
      chrome::kChromeUIScheme,
    };
    for (size_t j = 0; j < arraysize(schemes); ++j) {
      if (i->MatchesScheme(schemes[j])) {
        ((reason == UpdatedExtensionPermissionsInfo::REMOVED) ?
         WebSecurityPolicy::removeOriginAccessWhitelistEntry :
         WebSecurityPolicy::addOriginAccessWhitelistEntry)(
              extension->url(),
              WebString::fromUTF8(schemes[j]),
              WebString::fromUTF8(i->host()),
              i->match_subdomains());
      }
    }
  }
}

void ExtensionDispatcher::OnUpdatePermissions(
    int reason_id,
    const std::string& extension_id,
    const extensions::APIPermissionSet& apis,
    const URLPatternSet& explicit_hosts,
    const URLPatternSet& scriptable_hosts) {
  const Extension* extension = extensions_.GetByID(extension_id);
  if (!extension)
    return;

  scoped_refptr<const PermissionSet> delta =
      new PermissionSet(apis, explicit_hosts, scriptable_hosts);
  scoped_refptr<const PermissionSet> old_active =
      extension->GetActivePermissions();
  UpdatedExtensionPermissionsInfo::Reason reason =
      static_cast<UpdatedExtensionPermissionsInfo::Reason>(reason_id);

  const PermissionSet* new_active = NULL;
  switch (reason) {
    case UpdatedExtensionPermissionsInfo::ADDED:
      new_active = PermissionSet::CreateUnion(old_active, delta);
      break;
    case UpdatedExtensionPermissionsInfo::REMOVED:
      new_active = PermissionSet::CreateDifference(old_active, delta);
      break;
  }

  extension->SetActivePermissions(new_active);
  AddOrRemoveOriginPermissions(reason, extension, explicit_hosts);
}

void ExtensionDispatcher::OnUpdateTabSpecificPermissions(
    int page_id,
    int tab_id,
    const std::string& extension_id,
    const URLPatternSet& origin_set) {
  RenderView* view = TabFinder::Find(tab_id);

  // For now, the message should only be sent to the render view that contains
  // the target tab. This may change. Either way, if this is the target tab it
  // gives us the chance to check against the page ID to avoid races.
  DCHECK(view);
  if (view && view->GetPageId() != page_id)
    return;

  const Extension* extension = extensions_.GetByID(extension_id);
  if (!extension)
    return;

  extension->UpdateTabSpecificPermissions(
      tab_id,
      new PermissionSet(APIPermissionSet(), origin_set, URLPatternSet()));
}

void ExtensionDispatcher::OnClearTabSpecificPermissions(
    int tab_id,
    const std::vector<std::string>& extension_ids) {
  for (std::vector<std::string>::const_iterator it = extension_ids.begin();
       it != extension_ids.end(); ++it) {
    const Extension* extension = extensions_.GetByID(*it);
    if (extension)
      extension->ClearTabSpecificPermissions(tab_id);
  }
}

void ExtensionDispatcher::OnUpdateUserScripts(
    base::SharedMemoryHandle scripts) {
  DCHECK(base::SharedMemory::IsHandleValid(scripts)) << "Bad scripts handle";
  user_script_slave_->UpdateScripts(scripts);
  UpdateActiveExtensions();
}

void ExtensionDispatcher::UpdateActiveExtensions() {
  // In single-process mode, the browser process reports the active extensions.
  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess))
    return;

  std::set<std::string> active_extensions = active_extension_ids_;
  user_script_slave_->GetActiveExtensions(&active_extensions);
  child_process_logging::SetActiveExtensions(active_extensions);
}

void ExtensionDispatcher::RegisterExtension(v8::Extension* extension,
                                            bool restrict_to_extensions) {
  if (restrict_to_extensions)
    restricted_v8_extensions_.insert(extension->name());

  RenderThread::Get()->RegisterExtension(extension);
}

void ExtensionDispatcher::OnUsingWebRequestAPI(
    bool adblock, bool adblock_plus, bool other) {
  webrequest_adblock_ = adblock;
  webrequest_adblock_plus_ = adblock_plus;
  webrequest_other_ = other;
}

void ExtensionDispatcher::OnShouldUnload(const std::string& extension_id,
                                         int sequence_id) {
  RenderThread::Get()->Send(
      new ExtensionHostMsg_ShouldUnloadAck(extension_id, sequence_id));
}

void ExtensionDispatcher::OnUnload(const std::string& extension_id) {
  // Dispatch the unload event. This doesn't go through the standard event
  // dispatch machinery because it requires special handling. We need to let
  // the browser know when we are starting and stopping the event dispatch, so
  // that it still considers the extension idle despite any activity the unload
  // event creates.
  ListValue args;
  args.Set(0, Value::CreateStringValue(kOnUnloadEvent));
  args.Set(1, Value::CreateStringValue("[]"));
  v8_context_set_.DispatchChromeHiddenMethod(
      extension_id, kEventDispatchFunction, args, NULL, GURL());

  RenderThread::Get()->Send(new ExtensionHostMsg_UnloadAck(extension_id));
}

void ExtensionDispatcher::OnCancelUnload(const std::string& extension_id) {
  ListValue args;
  args.Set(0, Value::CreateStringValue(kOnSuspendCanceledEvent));
  args.Set(1, Value::CreateStringValue("[]"));
  v8_context_set_.DispatchChromeHiddenMethod(
      extension_id, kEventDispatchFunction, args, NULL, GURL());
}

Feature::Context ExtensionDispatcher::ClassifyJavaScriptContext(
    const std::string& extension_id,
    int extension_group,
    const ExtensionURLInfo& url_info) {
  if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) {
    return extensions_.Contains(extension_id) ?
        Feature::CONTENT_SCRIPT_CONTEXT : Feature::UNSPECIFIED_CONTEXT;
  }

  // We have an explicit check for sandboxed pages first since:
  // 1. Sandboxed pages run in the same process as regular extension pages, so
  //    the extension is considered active.
  // 2. ScriptContext creation (which triggers bindings injection) happens
  //    before the SecurityContext is updated with the sandbox flags (after
  //    reading the CSP header), so url_info.url().securityOrigin() is not
  //    unique yet.
  if (extensions_.IsSandboxedPage(url_info))
    return Feature::WEB_PAGE_CONTEXT;

  if (IsExtensionActive(extension_id))
    return Feature::BLESSED_EXTENSION_CONTEXT;

  if (extensions_.ExtensionBindingsAllowed(url_info)) {
    return extensions_.Contains(extension_id) ?
        Feature::UNBLESSED_EXTENSION_CONTEXT : Feature::UNSPECIFIED_CONTEXT;
  }

  if (url_info.url().is_valid())
    return Feature::WEB_PAGE_CONTEXT;

  return Feature::UNSPECIFIED_CONTEXT;
}

void ExtensionDispatcher::OnExtensionResponse(int request_id,
                                              bool success,
                                              const base::ListValue& response,
                                              const std::string& error) {
  request_sender_->HandleResponse(request_id, success, response, error);
}

bool ExtensionDispatcher::CheckCurrentContextAccessToExtensionAPI(
    const std::string& function_name) const {
  ChromeV8Context* context = v8_context_set().GetCurrent();
  if (!context) {
    DLOG(ERROR) << "Not in a v8::Context";
    return false;
  }

  if (!context->extension()) {
    v8::ThrowException(
        v8::Exception::Error(v8::String::New("Not in an extension.")));
    return false;
  }

  // We need to whitelist tabs.executeScript and tabs.insertCSS because they
  // are granted under special circumstances with the activeTab permission
  // (note that the browser checks too, so this isn't a security problem).
  //
  // Only the browser knows which tab this call will be sent to... sometimes we
  // *could* figure it out (if the extension gives an explicit tab ID in the
  // call), but the expected case will be the extension passing through -1,
  // meaning the active tab, and only the browser safely knows what this is.
  bool skip_permission_check = (function_name == "tabs.executeScript") ||
                               (function_name == "tabs.insertCSS");

  if (!skip_permission_check &&
      !context->extension()->HasAPIPermission(function_name)) {
    static const char kMessage[] =
        "You do not have permission to use '%s'. Be sure to declare"
        " in your manifest what permissions you need.";
    std::string error_msg = base::StringPrintf(kMessage, function_name.c_str());
    v8::ThrowException(
        v8::Exception::Error(v8::String::New(error_msg.c_str())));
    return false;
  }

  if (ExtensionAPI::GetSharedInstance()->IsPrivileged(function_name) &&
      context->context_type() != Feature::BLESSED_EXTENSION_CONTEXT) {
    static const char kMessage[] =
        "%s can only be used in an extension process.";
    std::string error_msg = base::StringPrintf(kMessage, function_name.c_str());
    v8::ThrowException(
        v8::Exception::Error(v8::String::New(error_msg.c_str())));
    return false;
  }

  // We should never end up with sandboxed contexts trying to invoke extension
  // APIs, they don't get extension bindings injected. If we end up here it
  // means that a sandboxed page somehow managed to invoke an API anyway, so
  // we should abort.
  WebKit::WebFrame* frame = context->web_frame();
  ExtensionURLInfo url_info(frame->document().securityOrigin(),
      extensions::UserScriptSlave::GetDataSourceURLForFrame(frame));
  CHECK(!extensions_.IsSandboxedPage(url_info));

  return true;
}


text:
Climate Change Alarmism Is 'Garbage In, Garbage Out,' Retired NASA Physicist Says
Posted Monday, November 27, 2017 | By Collaborative Correspondent | 3 Comments
HOUSTON—Unvalidated climate models that don't correspond with physical data and the requirements of the scientific method contribute to unfounded climate alarmism, a retired NASA physicist said at the Heartland Institute's recent America First Energy Conference.
Since America's national security depends in part on energy security, unsubstantiated claims about global warming that prevent policymakers from making "rational decisions" with regard to the development of U.S. energy resources have become a national security threat, said Hal Doiron, a 16-year NASA veteran.
The "propaganda" underpinning climate alarmism is "causing tremendous political bottlenecks" that prevent government officials from "doing the right thing" on energy, he said.
Doiron, who helped develop the Apollo Lunar Module's landing dynamics software during NASA's moon missions, also expressed concern that the U.S. military has been directly affected by climate alarmist claims separated from sound science.
He criticized the Navy for "preparing for something that is unreasonable and would cost too much money" in the form of "extreme sea-level rise," which has not been borne out by rigorous scientific study.
Doiron defines unvalidated climate models as those that do not agree with physical data. Public policy and military planning should be based only on models validated by physical data, he said.
"At NASA, we have a policy: You can't make a design decision on a spacecraft or rocket that is not validated," he said. "You don't make critical decisions based on 'garbage in, garbage out.' Yet our government has been doing that with respect to climate alarm, because too many academics in universities are writing papers, drawing conclusions from models that don't agree with physical data."
Doiron is part of a group called "The Right Climate Stuff," which includes engineers and scientists from across generations who have taken part in NASA's most high-profile missions dating back to Apollo.
The group has produced its own "rigorous, earth surface temperature model using conservation-of-energy principles" that operates similarly to the way the surface and internal temperature of a spacecraft is analyzed, the Right Climate Stuff team explains on its website.
The reports produced from the analysis provide more "realistic projections" of the rise in the earth's surface temperature over the next 150 years that show severe anti-fossil fuel regulations are not justified, Doiron and other former NASA team members contend.
"The scientific method requires that your hypothesis and theories be confirmed by physical data," he said. "Computer models are not physical data, although I think many in academia don't understand that."
When unvalidated models are compared with validated models based on physical evidence, the validated models predict much less global warming, Doiron said. Moreover, the fact that unvalidated models often don't agree with each other should be a "big, red flag."
The retired NASA physicist is calling for U.S. policymakers to establish official data on two key metrics; specifically, "the true sensitivity of surface temperature to greenhouse gases" and a "reasonable projection of greenhouse emissions and [the] concentrations rise in our atmosphere."
Doiron and his team have developed "a new metric" called "transient climate sensitivity," which measures how much warming can be seen with a doubling of carbon dioxide in the atmosphere in the "way that it's actually happening," based on a "very small amount of [carbon dioxide] each year."
That's something that can be measured and verified against available physical data, he said. But because policymakers, including military planners, are not operating from reasonable projections, they are not in a position to adequately plan for the future, Doiron cautioned.
Another way climate change alarmism has worked to undermine America's national security standing is by consuming too much of the military budget at the expense of military readiness, a top naval commander said during the panel discussion.
Adm. Thomas Hayward, who retired from the Navy as chief of naval operations and a member of the Joint Chiefs of Staff after serving as commander of the 7th Fleet and commander in chief of the Pacific Fleet, also addressed the Heartland Institute's energy conference and sounded concerns.
For the past six to eight years, Hayward said, climate change has been given "a higher priority" than the readiness of the Navy's fleet. During that time, the Defense Department has spent $100 billion on "just climate change," while the Navy has spent "$58 billion chasing what is called the 'green fleet.'"
That means many Navy vessels are using biofuels, but Hayward wonders how many ports around the world are equipped to accommodate Navy vessels that rely on a high percentage of biofuels, and he worries how that would work in a combat situation.
This report has been modified to state correctly how much Hayward said the Defense Department has spent on climate change.
From – The Daily Signal – by Kevin Mooney
Posted in Conservatives, Drain the Swamp, Freedom and liberty, globalization, Liberals, Operation Expose, Political Corruption,, Politics, Progressive Socialists, Progressives, Republicans
‹ PreviousTexas State Trooper Murdered During Traffic Stop on Thanksgiving; Suspected Killer Dabrett Black in Custody…
Next ›A Shout out to a service needed in the small business world of Australia …
One thought on "Junk Science…"
Brittius says:
11/28/2017 at C+00:001130Tue, 28 Nov 2017 17:47:34 +0000pmTuesday
Reblogged this on Brittius.

redpajama_set_name: RedPajamaCommonCrawl


A good love storyWith an intimation of sexual gratification which enhances the sisters mysterious powers. What will spark Marina's power to finally defeat "the master"?
Morganna Mayfair - Morganna Mayfair is a pen name of writer Kirsten Osbourne for her paranormal romance. Morganna has been writing all her life, but just forayed into the publishing world in 2011, and her life has been forever changed. She lives in Texas with her husband, son, and a menage of pets that make her crazy. She can't wait to share her stories with you!


text:
Legends of Film: Brian Trenchard Smith
During this episode Bill talks to director Brian Trenchard Smith. Mr. Trenchard Smith's credits include Dead End Drive In, BMX Bandits, Turkey Shoot, and the upcoming Movies @ Main feature The Siege of Firebase Gloria. Trenchard Smith discusses the making of the film, and also talks about the best stunt he ever directed.
Join us for a free screening of The Siege of Firebase Gloria on Saturday, September 14th at 2:00 p.m. in the first floor auditorium.
Legends of Film Podcast


text:
Debate camp transitions online
Mean Green Comet Debate Institute has more than 250 high-school and middle-school student participants.
Anjali Venna
Camp leadership navigates software to shift workshops to remote format
Despite being miles apart, students discuss strategy in separate virtual rooms for one round of a debate competition. This is how students will practice debate this summer at the Mean Green Comet Debate Institute, which is transitioning to an online format due to COVID-19.
Bringing together more than 250 students at the high-school and middle-school level, the camp prepares attendees for the fall and spring competitive debate seasons. The paid camp has taken place each summer for the past 12 years, but four years ago, the UTD camp merged with the UNT Mean Green debate workshop. Sessions for the various divisions, such as Policy Debate and Public Forum, run from late June to mid-July.
In previous years, camp attendees went to classes and lectures from nine to five. Now, instruction will occur through Blackboard Collaborate. Camp leadership anticipated the online transition early March, director of debate Scott Herndon said, and began working with the Office of Information Technology to take advantage of the various features Blackboard has to offer.
"You can't just take brick and mortar school, and plug it into an online environment and say 'okay kids, sit in front of your computer for nine hours a day,'" Herndon said. "We don't learn that way."
One useful feature, Herndon said, is the ability to record each lecture for students who may have missed part of a discussion. Another one is breakout rooms, separate virtual rooms that instructors can assign students into. In these rooms, students would be able to work in smaller groups on specific skills or give speeches and receive feedback.
Part of the camp experience, Herndon said, is a debate tournament conducted at the end of each session. This experience will be translated virtually via Microsoft Teams. Five people, four debaters and one judge will have a video meeting for each round of the competition. The debaters, who compete in groups of two, will have their own separate chat or breakout room to collaborate, though the actual debate will occur in a main room that includes everyone.
"We're kind of at the front edge of this because we're just learning how to use these capabilities to make debates happen. So I expect there to be some hiccups, but at the same time we've got a pretty good platform for it and our tests have worked really well," Herndon said. "I think everybody misses that sense of connection that you have when you're right there with your partner, you're all in the same room. There's energy to that that's missing in this format, but there's also some excitement to see how, even after quarantine, if we can use this technology to make what we do more effective."
Technological hurdles included working out eLearning access for students and how to handle troubleshooting. Other similar debate programs such as the Michigan National Debate Institute and Jayhawk Debate Institute are moving online as well. Herndon said they had a desire to be in front of the change.
"We didn't want to be reacting to it. I would rather make my own mistakes and figure it out. Nobody has a template to work off of," Herndon said. "We have really bright people involved, and we trusted ourselves to figure it out."
Initial concerns involved how the registration process would change, how to keep students engaged and how to organize each day of camp. Specifically, Herndon said he and his team were cognizant of asynchronous and synchronous learning styles as they designed the new virtual format.
"Synchronous is the way you do things in class. You're there in person with the teacher and you're all in guided learning together. Asynchronous means you do a lot of things on your own. It's more designed to chunk time," Herndon said. "We're hoping to provide an environment that allows students the flexibility to get the most out of the camp but not on a schedule that's locking them into a room where they sit one on one by themselves and stare at a screen."
For instance, in the morning, students meet for class and lecture in a group video call. Then they are split into groups to work independently for two hours, though staff would remain available for guidance. After lunch students reconvene for speech drills and other activities.
Despite the challenges of moving online, Herndon said, overhead costs, such as room and board and meals, went down. However, since they are designing an online course from scratch, the single biggest cost, he said, is time.
"Crisis really brings out the best in people, and the entire experience of rebuilding the camp, and really thinking through what we do and why we do it has been just an eye-opening and educational moment for me," Herndon said. "The goal is to get back to an in-person camp but at the same time I think we're going to learn a lot that makes what we do in person better, too. This is going to make all of us better teachers."
Changes to JSOM community service requirement
'Coexist with COVID-19'


If you're planning for a unique experience in Orlando, Florida, and If you're a big fan of alligators, and its bigger cousins the crocodiles to a lesser extent, then here's a theme park just for you! Surprised that such a place exists? Then read on to find out more about Gatorland Orlando!
If you've never heard of Gatorland Orlando, then you're in for a surprise because, despite the fact that it's not as the world popular like Disney Orlando or Universal Studios, Gatorland has its own unique theme that makes them stand out from the other theme parks in Orlando, Florida.
If you're curious to check out Gatorland Orlando, getting yourself familiar with the park as you prepare to embark on a trip is a little tricky because you're learning about a new place that not many people, especially those living outside the country, know. So sit back and read on everything you need to know about Gatorland, how to prepare a trip to Gatorland, and what you can expect from a gator-themed park.
The park was first opened in 1949 by Owen Godwin, who used a large part of his family's private land that was previously used for cattle and ranchers, into a large theme park. He did so because he wanted Gatorland Orlando to be the "Alligator Capital of the World." And indeed it is, with thousands of alligators and crocodiles in habitats, a breeding marsh where guests can see these reptiles especially during mating season, an observation tower, reptile shows, a petting zoo, swamp walk, an aviary for bird lovers, and even educational programs.
One of its oldest and its more iconic attractions is a train called the Gatorland Express, or previously known as Ol' Iron Horse Express. First opened in 1961, it was originally built by the Allan Herschell Company. Many believe it to be the oldest amusement attraction in Central Florida. Unfortunately, with age, everything eventually comes to an end. And in 2000, the original locomotive was retired and put on display, but its newer model built and donated by Train Rides Unlimited still runs to this day. This new model, as it turns out, is the very same one you would see at the Green Meadows Petting Farm. On the flip side, you would need to pay an additional fee in order to ride the express.
For a more thrilling experience, a new attraction was introduced into the park in 2011 – a zip line ride. This zip line stretches across a pool of alligators, which then goes further and over several other attractions. The zip line ride is 1,200 feet long, several stories high, This is definitely a great way to get noticed! It got even better in 2016 when Gatorland made the zip line accessible for people in wheelchairs.
Lastly, the center of the park itself, Gator Spot. Here is where guests can meet the alligators, where they can feed them and even take photos with them. It opened at Fun Spot America Theme Parks on May 11, 2015. This new addition allowed Gatorland to extend their brand, meaning more visitors will be able to experience what Gatorland has to offer. And if you can, why take some photos with the star of the Gator Spot, a leucistic blue-eyed alligator named Bouya?
Gatorland Orlando has many different restaurants that you can go have a food trip at, all serving all-American favorites, below is a complete list of restaurants you can find.
Opened in 1991 this restaurant immediately became a favorite for Gatorland's visitors. Everything you'd expect Americans would love is right there, from hamburgers, hotdogs, pulled pork sandwiches, ice cream, and so much more. But the main feature of this restaurant is the fried gator nuggets. Made from gator meat, and not the ones used for the park itself, guests just simply love its crispiness and juiciness! You can find Pearl's Steakhouse near the World Famous Gator Wreslin' Arena and is open 24/7.
One of Gatorland's older eating joints currently available. Opened in 1965, the Gatorland Snack Bar as it has become known has provided hungry guests with an array of delicious Southern delicacies 24/7. And it may be called a snack bar, but its food is sure to sate the hunger of even the pickiest eaters. Another feature the Snackbar has over the other dining places is that it offers a Kids Meal for the kids, which mainly comprises of either a hotdog or a peanut butter and jelly sandwich. Other Kids Meal includes cookies, goldfish crackers, and drinks.
If you're up for something sweet, this little stand offers the best fudge you can find in Gatorland Orlando. Owned by a man named Derek Keleghan, this individual from Ireland brings delicious fudge all made with the freshest ingredients. You can also find 10 other varieties of flavors of fudge to choose from like chocolate, chocolate pecan, chocolate caramel, rocky road, oreo, maple pecan, praline, chocolate peanut butter, and just plain old peanut butter! Even more, Derek makes his own caramel and candies, chocolate and caramel apples, chocolate dipped marshmallows, pretzels glazed in chocolate, and his most popular creation, the chocolate alligator on a stick!
Not up for eating but would rather have a cold drink during a warm day? The general store has it all just for you. Located near the Gator Gully Splash Park, this little country store sells not just cold drinks, but also gifts and ice cream bars. Once you buy your drink and/or ice cream bar, you can go enjoy the day on the store's patio, a perfect spot to relax and cool off. Also, note that the General Store serves drinks both alcoholic and non-alcoholic.
Something to perk up your day featuring a variety of beverages, from regular coffee to tea, fruit smoothies and tea. If you're not hungry for snacks but thirsty for some coffee, this place is for you. This is located next to the Screamin' Gator Zip Line Depot.
What else is there to do for friends, family, or groups of large people?
Now, once the day is over, you would think you can just simply get out and go home, right? Gatorland can host a variety of events for you, your friends and your family, or even for your co-workers! From birthday parties to corporate events, camping, field trips, Orlando Lake Tours, and even off-property events!
And if you decide to hold a corporate event in Gatorland Orlando, you'll get 700 square feet of meeting space and over 1200 security guards for better protection. Event types include a regular BBQ event or a formal event. Of course, these events can be customized further, with options including catering, free park admission, zipline tours, and behind-the-scenes tours.
Are you a teacher or a principal who wants to plan a day for students to have a great time at Gatorland Orlando? Then you can let them experience what it's like to get up and close with Gatorland's reptiles and other animals, which are both educational and makes for a unique experience to bond with animals! For further planning, you can contact group sales, as well as to learn more about the different options to further enhance the trip, such as free parking spaces and student discounts.
Whether you're a company, a small business, or even a group of people who want to do a little team building session at Gatorland Orlando, then they have you covered, too! Because they believe a stronger bond between teammates can be achieved with the Gator Zip Line, which is up to seven stories tall with 1200 feet of zip line, people can feel what it's like to soar through the air as they work to strengthen their bonds, combined with Gatorland's state-of-the-art meeting amenities at the Crocodile Conference Room that holds up to 40 people, different meal options, seating options, as well as different team building events such as alligator and encounters, scavenger hunts, and so much more.
Single day admission to Gatorland.
Our Rookie Wrestin' Experience where you get to step onto the sand at the world famous Gator Wrestlin' Arena and feel the power of one of the most feared creatures in the world. A $10 value. (Photo not included).
Unlimited train rides on the Gatorland Express train throughout the park! A $2 value.
Gator Chow! – Gatorland is the only safe place to see an alligator, and you can too with our Gator Chow, included in the Gatorland Grunt Package. A $3 value.
Adult price – $33.99 plus tax.
Child price – 26.99 plus tax.
Thinking of booking a ticket as part of your Pre Florida Checklist? Gatorland Orlando offers many different tickets, each with their own different price.
Single day admissions depend on the day, but as of September 2017, an Adult Grunt Package costs $33.99 per day, a Child Grunt Package costs $26.99 per day, an Adult admission costs $23.99 per day, and a child admission fee costs $15.99 per day.
Now, as for the different rides, each ticket has a different price depending on the month just like the admission fees above. First, the Zip Line admissions, which is at $69.99 as of September 2017, the Gatorland Express is currently set at $2 per head but with unlimited use, the Trainer for a Day ticket is set at $139.99 per head and the Night Shine ticket at $24.99 per head. For annual passes, per head, adults are $39.99, children $27.99, and seniors at $36.99.
Gatorland Florida may not be the most well-known theme park worldwide, but the fact that they offer their own unique experiences to guests in their attractions and their animal encounter activities, you'll definitely be happy to get to know alligators, crocodiles, and other animals more once you visit Gatorland Florida. After all, what other adventure theme park can let you get close with critters that you normally don't encounter every day? So what are you waiting for? Book your tickets and get ready for an experience of a lifetime!
Next articleWhat Makes Naples Beach Florida a Stunning Tourist Spot?


text:
package tests

import (
	"context"
	"encoding/binary"
	"net/url"
	"strings"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"github.com/googleapis/cloud-bigtable-clients-test/testproxypb"
	"github.com/stretchr/testify/assert"
	btpb "google.golang.org/genproto/googleapis/bigtable/v2"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
	"google.golang.org/protobuf/testing/protocmp"
	"google.golang.org/protobuf/types/known/durationpb"
)

// dummyReadModifyWriteRowRequest returns a dummy ReadModifyWriteRowRequest.
// ReadModifyWriteRules are built from interleved "increment" and "append" actions.
// The columns are "f:col_str" and "f:col_int".
func dummyReadModifyWriteRowRequest(tableID string, rowKey []byte, increments []int64, appends []string) *btpb.ReadModifyWriteRowRequest {
	req := &btpb.ReadModifyWriteRowRequest{
		TableName: buildTableName(tableID),
		RowKey:    rowKey,
		Rules:	   []*btpb.ReadModifyWriteRule{},
	}

	i := 0
	ruleAdded := false
	for {
		if i < len(increments) {
			rule := &btpb.ReadModifyWriteRule{
				FamilyName:      "f",
				ColumnQualifier: []byte("col_int"),
				Rule:            &btpb.ReadModifyWriteRule_IncrementAmount{IncrementAmount: increments[i]},
			}
			req.Rules = append(req.Rules, rule)
			ruleAdded = true
		}
		if i < len(appends) {
			rule := &btpb.ReadModifyWriteRule{
				FamilyName:      "f",
				ColumnQualifier: []byte("col_str"),
				Rule:            &btpb.ReadModifyWriteRule_AppendValue{AppendValue: []byte(appends[i])},
			}
			req.Rules = append(req.Rules, rule)
			ruleAdded = true
		}
		if !ruleAdded {
			break
		}
		i += 1
		ruleAdded = false
	}
	return req
}

// dummyResultRow returns a row after applying ReadModifyWriteRules to a blank row.
// ReadModifyWriteRules are built from "increment" and "append" actions.
// The columns are f:col_str and f:col_int.
func dummyResultRow(rowKey []byte, increments []int64, appends []string) *btpb.Row {
	resultNum := int64(0)
	for _, num := range increments {
		resultNum += num
	}
	resultNumInBytes := make([]byte, 8)
	binary.BigEndian.PutUint64(resultNumInBytes, uint64(resultNum))

	resultStr := ""
	for _, str := range appends {
		resultStr += str
	}

	row := &btpb.Row{
		Key:      rowKey,
		Families: []*btpb.Family{
			&btpb.Family{
				Name: "f",
				Columns: []*btpb.Column{
					&btpb.Column{
						Qualifier: []byte("col_int"),
						Cells:     []*btpb.Cell{&btpb.Cell{TimestampMicros: 2000, Value: resultNumInBytes}},
					},
					&btpb.Column{
						Qualifier: []byte("col_str"),
						Cells:     []*btpb.Cell{&btpb.Cell{TimestampMicros: 1000, Value: []byte(resultStr)}},
					},
				},
			},
		},
	}
	return row
}

// TestReadModifyWriteRow_Generic_Headers tests that ReadModifyWriteRow request has client and
// resource info, as well as app_profile_id in the header.
func TestReadModifyWriteRow_Generic_Headers(t *testing.T) {
	// 0. Common variables
	const profileID string = "test_profile"
	const tableID string = "table"
	increments := []int64{10, 2}
	appends := []string{"str1", "str2"}
	rowKey := []byte("row-01")
	tableName := buildTableName(tableID)

	// 1. Instantiate the mock server
	// Don't call mockReadRowsFn() as the behavior is to record metadata of the request
	mdRecords := make(chan metadata.MD, 1)
	server := initMockServer(t)
	server.ReadModifyWriteRowFn = func(ctx context.Context, req *btpb.ReadModifyWriteRowRequest) (*btpb.ReadModifyWriteRowResponse, error) {
		md, _ := metadata.FromIncomingContext(ctx)
		mdRecords <- md

		return &btpb.ReadModifyWriteRowResponse{Row: dummyResultRow(rowKey, increments, appends)}, nil
	}

	// 2. Build the request to test proxy
	req := testproxypb.ReadModifyWriteRowRequest{
		ClientId: t.Name(),
		Request: dummyReadModifyWriteRowRequest(tableID, rowKey, increments, appends),
	}

	// 3. Perform the operation via test proxy
	opts := clientOpts{
		profile: profileID,
	}
	doReadModifyWriteRowOp(t, server, &req, &opts)

	// 4. Check the request headers in the metadata
	md := <-mdRecords
	if len(md["user-agent"]) == 0 && len(md["x-goog-api-client"]) == 0 {
		assert.Fail(t, "Client info is missing in the request header")
	}

	resource := md["x-goog-request-params"][0]
        if !strings.Contains(resource, tableName) && !strings.Contains(resource, url.QueryEscape(tableName)) {
		assert.Fail(t, "Resource info is missing in the request header")
	}
	assert.Contains(t, resource, profileID)
}

// TestReadModifyWriteRow_NoRetry_MultiValues tests that client can increment & append multiple values.
func TestReadModifyWriteRow_NoRetry_MultiValues(t *testing.T) {
	// 0. Common variables
	increments := []int64{10, 2}
	appends := []string{"str1", "str2"}
	rowKey := []byte("row-01")
	clientReq := dummyReadModifyWriteRowRequest("table", rowKey, increments, appends)

	// 1. Instantiate the mock server
	recorder := make(chan *readModifyWriteRowReqRecord, 1)
	action := &readModifyWriteRowAction{row: dummyResultRow(rowKey, increments, appends)}
	server := initMockServer(t)
	server.ReadModifyWriteRowFn = mockReadModifyWriteRowFnSimple(recorder, action)

	// 2. Build the request to test proxy
	req := testproxypb.ReadModifyWriteRowRequest{
		ClientId: t.Name(),
		Request:  clientReq,
	}

	// 3. Perform the operation via test proxy
	res := doReadModifyWriteRowOp(t, server, &req, nil)

	// 4. Check that the dummy request is sent and the dummy row is returned
	checkResultOkStatus(t, res)
	loggedReq := <-recorder
	if diff := cmp.Diff(clientReq, loggedReq.req, protocmp.Transform()); diff != "" {
		t.Errorf("diff found (-want +got):\n%s", diff)
	}
	assert.Equal(t, rowKey, res.Row.Key)
	assert.Equal(t, 10 + 2, int(binary.BigEndian.Uint64(res.Row.Families[0].Columns[0].Cells[0].Value)))
	assert.Equal(t, "str1" + "str2", string(res.Row.Families[0].Columns[1].Cells[0].Value))
}

// TestReadModifyWriteRow_Generic_MultiStreams tests that client can have multiple concurrent streams.
func TestReadModifyWriteRow_Generic_MultiStreams(t *testing.T) {
	// 0. Common variables
	increments := []int64{10, 2}
	appends := []string{"append"}
	rowKeys := []string{"op0-row", "op1-row", "op2-row", "op3-row", "op4-row"}
	concurrency := len(rowKeys)
	const requestRecorderCapacity = 10

	// 1. Instantiate the mock server
	recorder := make(chan *readModifyWriteRowReqRecord, requestRecorderCapacity)
	actions := make([]*readModifyWriteRowAction, concurrency)
	for i := 0; i < concurrency; i++ {
		actions[i] = &readModifyWriteRowAction{
			row: dummyResultRow([]byte(rowKeys[i]), increments, appends),
			delayStr: "2s"}
	}
	server := initMockServer(t)
	server.ReadModifyWriteRowFn = mockReadModifyWriteRowFnSimple(recorder, actions...)

	// 2. Build the requests to test proxy
	reqs := make([]*testproxypb.ReadModifyWriteRowRequest, concurrency)
	for i := 0; i < concurrency; i++ {
		clientReq := dummyReadModifyWriteRowRequest("table", []byte(rowKeys[i]), increments, appends)
		reqs[i] = &testproxypb.ReadModifyWriteRowRequest{
			ClientId: t.Name(),
			Request:  clientReq,
		}
	}

	// 3. Perform the operations via test proxy
	results := doReadModifyWriteRowOps(t, server, reqs, nil)

	// 4a. Check that all the requests succeeded
	assert.Equal(t, concurrency, len(results))
	checkResultOkStatus(t, results...)

	// 4b. Check that the timestamps of requests should be very close
	assert.Equal(t, concurrency, len(recorder))
	checkRequestsAreWithin(t, 1000, recorder)

	// 4c. Check the row keys in the results.
	for i := 0; i < concurrency; i++ {
		assert.Equal(t, rowKeys[i], string(results[i].Row.Key))
	}
}

// TestReadModifyWriteRow_NoRetry_TransientError tests that client doesn't retry on transient errors.
func TestReadModifyWriteRow_NoRetry_TransientError(t *testing.T) {
	// 0. Common variables
	increments := []int64{10, 2}
	appends := []string{"str1", "str2"}
	rowKey := []byte("row-01")
	clientReq := dummyReadModifyWriteRowRequest("table", rowKey, increments, appends)

	// 1. Instantiate the mock server
	records := make(chan *readModifyWriteRowReqRecord, 2)
	actions := []*readModifyWriteRowAction{
		&readModifyWriteRowAction{rpcError: codes.Unavailable},
		&readModifyWriteRowAction{row: dummyResultRow(rowKey, increments, appends)},
	}
	server := initMockServer(t)
	server.ReadModifyWriteRowFn = mockReadModifyWriteRowFn(records, actions)

	// 2. Build the request to test proxy
	req := testproxypb.ReadModifyWriteRowRequest{
		ClientId: t.Name(),
		Request:  clientReq,
	}

	// 3. Perform the operation via test proxy
	res := doReadModifyWriteRowOp(t, server, &req, nil)

	// 4. Check that the result has error, and there is no retry
	assert.NotEmpty(t, res)
	assert.Equal(t, int32(codes.Unavailable), res.GetStatus().GetCode())
	assert.Equal(t, 1, len(records))
}

// TestReadModifyWriteRow_GenericClientGap_CloseClient tests that client doesn't kill inflight requests
// after client closing, but will reject new requests.
func TestReadModifyWriteRow_GenericClientGap_CloseClient(t *testing.T) {
	// 0. Common variable
	increments := []int64{10, 2}
	appends := []string{"append"}
	rowKeys := []string{"op0-row", "op1-row", "op2-row", "op3-row", "op4-row", "op5-row"}
	halfBatchSize := len(rowKeys) / 2
	clientID := t.Name()
	const requestRecorderCapacity = 10

	// 1. Instantiate the mock server
	recorder := make(chan *readModifyWriteRowReqRecord, requestRecorderCapacity)
	actions := make([]*readModifyWriteRowAction, 2 * halfBatchSize)
	for i := 0; i < 2 * halfBatchSize; i++ {
		actions[i] = &readModifyWriteRowAction{
			row: dummyResultRow([]byte(rowKeys[i]), increments, appends),
			delayStr: "2s",
		}
	}
	server := initMockServer(t)
	server.ReadModifyWriteRowFn = mockReadModifyWriteRowFnSimple(recorder, actions...)

	// 2. Build the requests to test proxy
	reqsBatchOne := make([]*testproxypb.ReadModifyWriteRowRequest, halfBatchSize) // Will be finished
	reqsBatchTwo := make([]*testproxypb.ReadModifyWriteRowRequest, halfBatchSize) // Will be rejected by client
	for i := 0; i < halfBatchSize; i++ {
		reqsBatchOne[i] = &testproxypb.ReadModifyWriteRowRequest{
			ClientId: clientID,
			Request: dummyReadModifyWriteRowRequest("table", []byte(rowKeys[i]), increments, appends),
		}
		reqsBatchTwo[i] = &testproxypb.ReadModifyWriteRowRequest{
			ClientId:  clientID,
			Request: dummyReadModifyWriteRowRequest(
				"table", []byte(rowKeys[i + halfBatchSize]), increments, appends),
		}
	}

	// 3. Perform the operations via test proxy
	setUp(t, server, clientID, nil)
	defer tearDown(t, server, clientID)

	closeClientAfter := time.Second
	resultsBatchOne := doReadModifyWriteRowOpsCore(t, clientID, reqsBatchOne, &closeClientAfter)
	resultsBatchTwo := doReadModifyWriteRowOpsCore(t, clientID, reqsBatchTwo, nil)

	// 4a. Check that server only receives batch-one requests
	assert.Equal(t, halfBatchSize, len(recorder))

	// 4b. Check that all the batch-one requests succeeded
	checkResultOkStatus(t, resultsBatchOne...)
	for i := 0; i < halfBatchSize; i++ {
		assert.Equal(t, rowKeys[i], string(resultsBatchOne[i].Row.Key))
	}

	// 4c. Check that all the batch-two requests failed at the proxy level:
	// the proxy tries to use close client. Client and server have nothing to blame.
	// We are a little permissive here by just checking if failures occur.
	for i := 0; i < halfBatchSize; i++ {
		if resultsBatchTwo[i] == nil {
			continue
		}
		assert.NotEmpty(t, resultsBatchTwo[i].GetStatus().GetCode())
	}
}

// TestReadModifyWriteRow_Generic_DeadlineExceeded tests that client-side timeout is set and
// respected.
func TestReadModifyWriteRow_Generic_DeadlineExceeded(t *testing.T) {
	// 0. Common variables
	increments := []int64{10, 2}
	appends := []string{"str1", "str2"}
	rowKey := []byte("row-01")
	clientReq := dummyReadModifyWriteRowRequest("table", rowKey, increments, appends)

	// 1. Instantiate the mock server
	recorder := make(chan *readModifyWriteRowReqRecord, 1)
	action := &readModifyWriteRowAction{
		row: dummyResultRow(rowKey, increments, appends),
		delayStr: "10s",
	}
	server := initMockServer(t)
	server.ReadModifyWriteRowFn = mockReadModifyWriteRowFnSimple(recorder, action)

	// 2. Build the request to test proxy
	req := testproxypb.ReadModifyWriteRowRequest{
		ClientId: t.Name(),
		Request: clientReq,
	}

	// 3. Perform the operation via test proxy
	opts := clientOpts{
		timeout: &durationpb.Duration{Seconds: 2},
	}
	res := doReadModifyWriteRowOp(t, server, &req, &opts)

	// 4a. Check the runtime
	curTs := time.Now()
	loggedReq := <-recorder
	runTimeSecs := int(curTs.Unix() - loggedReq.ts.Unix())
	assert.GreaterOrEqual(t, runTimeSecs, 2)
	assert.Less(t, runTimeSecs, 8) // 8s (< 10s of server delay time) indicates timeout takes effect.

	// 4b. Check the DeadlineExceeded error
	assert.Equal(t, int32(codes.DeadlineExceeded), res.GetStatus().GetCode())
}

redpajama_set_name: RedPajamaGithub


In continuation of our Grace Series, we want to look at the three major works of grace in the believer's life. We have had two titles in this series. The first explained the meaning of grace, in part, and stressed how it should be reflected in our relations with others. The second was a testimony of grace derived from my interactions with some believers online. You can click'on their titles to read.
Without the grace of God, we would still be separated from Him, condemned to die for our sins. That is the first major work of grace in our lives as children of God.
"For by grace you have been saved through faith. And this is not your own doing; it is the gift of God" – Ephesians 2:8.
"For the grace of God has appeared, bringing salvation for all people" – Titus 2:11.
A ransom was needed (one we couldn't pay) to buy us out from suffering God's judgment for sin, which is death, and Jesus, the Son of God took our place.
"For Christ also suffered once for sins, the righteous for the unrighteous, that he might bring us to God, being put to death in the flesh but made alive in the spirit" – 1 Peter 3:18.
2. We overcome sin and stand firm in trials by grace.
So Christ died in our place and we have life, then what? Do we have the liberty to do as we please because His grace covers us and God's mercy endures forever? Certainly not! The very reason God sent His Son to die for us is that He hates sin and we cannot have fellowship with Him if we persist in sin. Look at the Bible's descriptions of God through the prophet Habakkuk and King David.
"You who are of purer eyes than to see evil and cannot look at wrong" – Habakkuk 1:13a.
Being saved does not immediately translate us to heaven physically. We are still in a world that hates God and is full of temptation to do wrong. Grace comes in again and we see its second major work in the Christian's life.
Here is the continuation of the scripture we read earlier from Titus. In fact, we take verse 11 again and go further.
We may make mistakes along the way and our God understands our frailties and the stiff contest between our flesh and reborn spirit in its quest to live a life that glorifies Him. Jesus intercedes for us and His indwelling Spirit keeps helping us.
"For we do not have a high priest who is unable to sympathize with our weaknesses, but one who in every respect has been tempted as we are, yet without sin.
From the foregoing, we see that there is no biblical basis for living in unrepentant sin in the name of grace. This is not a new attraction. Paul adddressed it in the early church.
Besides battling with temptations, believers also face trials and persecution. God's grace helps us to endure and hold on to our faith in the face of these.
The Lord Jesus is our greatest example in this. His Passion was a complete work of grace. His flesh shrank from the humiliation and the agony of the Cross as we see in the prayers He prayed in the Garden of Gethsemane but He persevered and drank the bitter cup by grace (Matthew 26:36-44).
3. Grace enables us to do the work of God's kingdom.
As God grants us victory over sin and temptations, and makes us patient in trials by His grace, we see ourselves growing in our faith (James 1:2-4). He then begins to give us responsibilities. We don't remain babies forever. He sends us to share the gospel, heal the sick, teach and strengthen the saved, etc. But many of the tasks God assigns us cannot be accomplished in our own power or wisdom. In comes the grace again.
"Wherefore we receiving a kingdom which cannot be moved, let us have grace, whereby we may serve God acceptably with reverence and godly fear" – Hebrews 12:28 (KJV).
In Ephesians 4:7, this is what the apostle Paul said before discussing maturity, spiritual offices and the work of the ministry.
"But unto every one of us is given grace according to the measure of the gift of Christ" – Ephesians 4:7 (KJV).
The apostle Peter, on his part, described the work of ministry as stewardship of God's grace.
"As each has received a gift, use it to serve one another, as good stewards of God's varied grace" – 1 Peter 4:10.
It is the grace that enables someone to perform miracles and see souls converted, to speak timely words on hidden matters in the lives of strangers and to teach and fortify the faith of the saints. None of it can be accounted for by human skill or knowledge.
It goes without saying that if we aspire to see victory over sin, steadfastness in the face of trials and fruit that abides unto eternal life in our ministry, we need to allow God do the first major work of grace in our life. We must accept Jesus as our Lord and Saviour. If you haven't done that, pray now surrendering to Him so that you can properly begin the journey of faith and enjoy the grace God has abundantly poured forth for us in Christ.
The Grace Series will continue with a look at grace in the life of the Apostle Paul.
The scriptures used in this study are from the English Standard Version except where otherwise stated.
Thank you so much, my brother. While there is time .... You're awesomely blessed in Jesus' name.
Our God is merciful but He hates sin. His grace can help us live in a way that is pleasing to Him.
Hmmmm! These things you're saying need a megaphone, Collins, don't you think? Keep going and make it louder in Jesus' name. But remember the farmer eats the harvest before others. You are richly blessed in Jesus' name.
Thank you for visiting, Chizobam, and for your kind words. May we overflow with grace as we go about our Father's business in Jesus' name.
Very true. Thank you, Nneoma!
Amen. Where, indeed, shall we be without God's grace? Bless you, Rita!
Yes, thank God for His grace. Thanks for sharing!
Grace: God's Riches at Christ's Expense. Thank you for a great post!
Thank you, Kathleen, for dropping by and for reminding me of that wonderful expression. You are blessed!
Oh that we would all embrace grace entirely! Thanks Edith!
The word 'Grace' is often teamed with mercy in the Scriptures - and that's such a great teaming! Grace itself is a major part of Who God truly is, and has been defined as: God's undeserved love and favour towards US! That's what Grace is!
Praise God! To think that we have that at our disposal always! It's simply awesome!
J.C, you need to be born again first of all. You can live above sin in your own power. But when you are saved, the Holy Ghost living in you will help remind you of God's word when temptation comes and give you the strength to resist it. That is how the grace works, my dear!
You are indeed and so am I, praise God!
Me too! Without His grace, our lives would be: one day, many troubles.
Thanks Aunty Edith for this wonderful piece. It brings clarity to the subject of Grace. God's holy nature is still the same yesterday, today and forever. There is never a time He condones sin. His grace is sufficient for us. God bless.
Yes, Richard, the availability of God's grace is not a licence for us to relax in sin. You are blessed as well.
Thank you for reminding me that I can do all things and overcome trials by the grace of God.
Yes, you can! Bless you, Miriam!
Amen, my dear! May that grace keep all of us who have put our faith in the Lord Jesus till we appear before the the great white throne in Jesus' name.
If salvation was by works and not grace, what filthy Christians we would be! Grace does it all.
Clearly understood ma. Is not all about me and my abilities or inabilities. Rather, is all about God who has made His grace available unto us. Glory be to God .
Amen! His grace gives us leverage in life. Hallelujah!
God's grace will always be sufficient for us Amen..bless you ma.
Infact, I would say that the life we are living today, our whole being, is all by the grace of God. He is our all and all. Nice one Ma, keep it up.
Grace is pertinent in every one's life. Grace overcomes sin, trials and tribulations and helps us preach the good news of the Lord. Ma, ride on and bombard us with more of the grace teachings. It is important for people like us, the younger generation.
lovely article. it really enriches those that read it.
The earlier we devote ourselves to him the better. tnk God for his mercy on us.
God's grace is ever sufficient. It's a privilege to be living in the time of grace, although most of us abuse it.
God's grace is all we truly need in this perilous world.
i am a product of Gods grace... God bless you ma.
God's grace is a privilege many seek. By His grace, we achieve completeness. Nice write-up Ma.
The grace of God is always with us for ever, as long as you believe the working power of the death of our lord Jesus Christ.
From my experience as a believer, I have realised that without grace, it is impossible to please God, just like without faith it is impossible to please God.
It not a story but a practical truth .it brings clarity to the subject of grace.there is never a time he condones sin.
As a believer, without the Grace of God in my life I am nothing. The grace of God is always sufficient.
God's grace is what holds any believer.it is our tenet....we are proof of his grace!hallelujah!!
Grace to me is God's love towards us. It's God's gift to us. It's God's full work not ours. Just like the Bible says that it's not by our might lest any man should boast. But it's not a liberty to continue in sin but to draw us to his loving nature.
Grace is God's endowed love on us that keeps us strong even in times of darkness .
God's grace aid us in the course of the work of sanctification. We recognize that many times and in many ways God's special love is such that he offers us help to live in a way that leads to sharing his life.


I made a simple router jig for radiusing the fingerboard. Found the instructions on another forum and tried to copy, as usual. Completely out of scrap wood, as usual. Let the three pictures speak more than 3000 words.
...and the steel bars sit on radiused ends. This time both ends have the Martin standard 16" radius, but one or both could be easily replaced to another radii, to make a compound radius from 16" to 20", for instance. With flat ends the same jig could be used for thicknessing the fingerboard blank before slotting as well.


The dropout rate is the percent of students that drop out of school in grades seven (7) through twelve (12).
The dropout data is extracted from the student information system each year on November 1st. The dropout definition holds schools accountable for students for the full school year, including summer school.
2011-12 through 2016-17 School Year Dropout Data is available through the OpenHouse with Supplemental Data on the Learning Environment tab.
Dropout Data is lagged one year, so 2017-18 school year data is not available at this time.


BUS WORKERS in Norwich took unofficial action last Saturday over traffic congestion caused by the opening of a new shopping centre. The drivers are all employees of First Eastern Counties, which is part of the multinational First Group.
Their action caused long delays around the city centre by simply obeying the law and driving within the bus lane. At one point a foreman came out to try to intimidate drivers into joining the other lane. He gave up after a while. Police arrived but could only look on as drivers obeyed the law. One driver said, "It's the council's fault-it was always going to cause chaos. They should close the city centre to cars, and extend the park and ride service. "There are already high levels of stress in this job. This just adds to it."


Telecom Minister Ravi Shankar Prasad said that the problem of call drops on BSNL Mobile networks is improving. The telecommunications department had reviewed the situation on weekly basis for the past two months to reduce call drops.
In an attempt to reduce the issue of call drops due to shortage of mobile towers, the government has taken a policy decision under which all buildings of Government of India must allow installation of towers. He also added that, direction were already given to Post Offices to allow mobile towers on rent at its buildings throughout the country.
Chief Ministers of Kerala and Andhra Pradesh had already responded to his Ministry's proposal for installation of network towers on government buildings.
"The number of call drops on the Bharat Sanchar Nigam Limited (BSNL) mobile phones had significantly declined after the BSNL increased number of its network towers," Telecom Minister said.
He clarified that it was wrong to presume that one can develop cancer due to radiation from mobile tower. Referring to reluctance by people to allow installation of towers at their premises fearing that radiations from towers may lead to spread of cancer, the Union Minister said there was no truth in it citing reports by the World Health Orgnization (WHO) and judgements by various courts.
"The experts from the BSNL have come to Bihar several times in the last few months and have done a survey on what all things are needed to improve the situation. Even Airtel, Vodafone is optimising and trying to improve the situation in different cities. Airtel is also setting up 10 BTS in Patna," he said.
Telecom Regulatory Authority of India (TRAI) was also considering to take tough action against telecom companies for call drops. As per the latest TRAI report, the call drop problem during peak hours has almost doubled in the last one year.
To improve the quality of service, BSNL Kerala Circle already started upgrading its existing mobile network by adding nearly 2000 new 3G mobile towers across the state.
Dear readers, please share your views and opinions about this latest news via comments with us. How many of you have faced the Call Drop Issue in BSNL Mobile Network. Please comment your location and details about call drop complaints.


Label: comforter set twin cotton. comforter set twin target. purple comforter set king. comforter set twin. where to buy a comforter set. comforter set twin xl. purple and gold comforter sets. comforter set twin xl dorm.
Label: king red and brown comforter sets. red and brown comforter sets. katelyn comforter set.
Label: goth comforter sets. gothic comforter sets. comforter sheet sets queen. gothic king size comforter sets. comforter set for guys. dark gothic comforter sets. paisley comforter set king.
Label: green toile comforter sets. toile comforter sets queen. black and cream comforter set. toile twin comforter sets. dena home comforter set. black toile comforter sets. comforter set for boys. tan toile comforter sets.
Label: jets. comforter. yellow comforter sets queen. set. doctor who comforter set. new. solid brown comforter sets. york.
Label: chevron twin comforter sets. chevron comforter sets. white comforter sets king. chevron comforter sets queen. 3 piece comforter set. chevron print comforter sets. black full comforter set. chevron comforter sets king.
Label: 6 piece twin comforter set. cosmo 6 piece comforter set. luxury king size comforter sets. 6 piece sienna comforter set. j queen comforter set. 6 piece davina comforter set. blue and silver comforter sets. cranston 6 piece comforter set.


text:
Julie Andrews's legendary career encompasses the Broadway and London stages, as well as multiple films, television shows, album releases, concert tours, directing assignments, and the world of children's publishing. In 2000 the title of Dame Commander of the British Empire was bestowed upon her by Queen Elizabeth II for lifetime achievements in the arts and humanities. Her many other honors include a Kennedy Center honor in the fall of 2001. She was married to film director Blake Edwards for forty-one years, and the couple have five children, ten grandchildren, and three great-grandchildren.
Emma Walton Hamilton is an award-winning writer, producer and arts educator. Together with her mother, Julie Andrews, she has written over thirty books for children and young adults. Emma is on the faculty of Stony Brook University's MFA in Creative Writing, where she serves as director of the Children's Lit Fellows and the Young Artists and Writers Project.
The Very Fairy Princess: Attitude of Gratitude
From the beloved mother-daughter team of Julie Andrews and Emma Walton Hamilton comes another delightful story in the #1 New York Times bestselling Very Fairy…
The Very Fairy Princess: A Spooky, Sparkly Halloween
Celebrate Halloween with the #1 New York Time bestselling Very Fairy Princess series by Julie Andrews and Emma Walton Hamilton!This eBook features Read-Aloud/Read-to-Me functionality (where…
The Very Fairy Princess: Graduation Girl!
The end of the school year is here, and Very Fairy Princess Gerry is getting ready to graduate! She always loves a celebration, but can't…
The Very Fairy Princess Sparkles in the Snow
The Winter Wonderland Festival is just around the corner, and Gerry knows this is her moment to SHINE. She's the most enthusiastic singer around, so…
The Very Fairy Princess: Teacher's Pet
In Very Fairy Princess: Teacher's Pet, bestselling authors Julie Andrews and Emma Walton Hamilton take on the theme of responsibility in another fun, sparkly adventure.…
The Very Fairy Princess Follows Her Heart
Say Happy Valentine's Day with the #1 New York Times bestselling Very Fairy Princess, in a new format with bonus stickers! Gerry makes beautiful cards…
The Very Fairy Princess: A Fairy Merry Christmas
It's almost Christmas, and for Geraldine that means it's time for snowflakes, presents, and decorations galore. When her mom suggests that their family exchange homemade…
Julie Andrews' Treasury for All Seasons
A vast array of poems old and new joyously celebrates each special day of the year, telling of New Year's resolutions, Valentine's Day love, Easter…
Libro.fm
AudioBooksNow.com
NookAudioBooks.com
The Very Fairy Princess: Here Comes the Flower Girl!
Gerry is asked to be the flower girl in Aunt Sue's wedding, and she couldn't be more excited. Her imagination runs wild with thoughts of…
The Very Fairy Princess
While her friends and family may not believe in fairies, Geraldine knows, deep down, that she is a VERY fairy princess. From morning to night,…
The Very Fairy Princess Takes the Stage
Everyone's favorite fairy princess is back and just in time for her ballet recital in this new picture book addition to the Julie Andrews Collection.…
Julie Andrews' Collection of Poems, Songs, and Lullabies
A deluxe treasury of family favorites selected by the bestselling mother-daughter team.Julie Andrews and Emma Walton Hamilton share a diverse mix of their most beloved…