text:
Indian Players Interviews	4 years ago
Interview with Prajnesh Gunneswaran
Sufyan Ibrahim
By Sufyan Ibrahim, 5th May, 2018.
Show class, have pride and display character. If you do, winning takes care of itself. – Paul Bryant.
Prajnesh Gunneswaran has had a dream last couple of months. It all started with his brave win in the deciding rubber of the Asia/Oceania Davis Cup tie against China in China. He beat the reigning Junior US Open singles and doubles champion, Yibing Wu. quite authoritatively. He seems to have carried that confidence and form to the pro circuit, and the results have shown in the last one month or so.
He recently won his first ATP Challenger title in Anning on the red clay in China, winning the $150K(+H) event (the highest level of Challengers that there is). He had lost out in his other only Challenger final, a couple of years back in Pune. The great run in the Challenger circuit has given him a chance to showcase his skill in the French Open Qualifying starting in a couple of weeks.
Amidst this hectic last couple of months, Prajnesh found some time to catch up with Indian Tennis Daily for an interview. He talks about his entire journey as a tennis pro in this free-wheeling chat.
Q) First of all, how does it feel to pull off that amazing victory in the deciding rubber of the Davis Cup for your country? Has that moment sunk in yet? What was your psychological framework before that match?
It took me a little while, but it definitely has. After the match when we were all sitting together, it sort of sunk in. It is probably the best feeling that I have ever had. I mean, it couldn't have come at a better time, you know, playing the 5th and deciding rubber for your country and coming out on top. It was an honor for me.
Honestly, I didn't think much before the match. I just knew that I had to play very aggressively. If I dwell too much on the weight of the situation, I wouldn't be able to play my game. So, I didn't let myself think too much about that. And fought it out on the court.
Celebrations! Embraced by Captain Mahesh Bhupathi and other teammates.
Q) You started playing tennis at the age of seven, but you've told it many times that you have played far fewer matches than your peers, owing to multifarious injuries that you had to go through. What would you want to tell about the current fitness regime that you are following? Any advice that you would want to give to the juniors?
I have been working with my German fitness trainer in Bengaluru, since the age of fourteen, who plans for my fitness sessions. He currently works with the Netherlands' BMX Olympic team. And also I also train at Schuttler-Waske along with that.
Advice is pretty simple: find the right support system, the right coach, obviously your parents will support you, and follow somebody who has achieved it previously so that you know you are on the right track as it could be very confusing sometimes.
Q) Could you elaborate a little bit about your background, what made you get into tennis? You family and financial support, etc.?
My grandfather was the one who got me into tennis in the first place. He had a passion for sports. My cousin used to play tennis and I used to follow her to the courts even when I was like a toddler. And I guess they saw that I had the interest to run behind the balls and discovered what I wanted to play. I was one of the first tods to play in the mini-courts in YMC when they were established.
Financial support initially by my granddad and then by my dad. Since then it has always been them and whatever I make from tennis.
Q) After having won the U-16 and U-18 titles, you seemed to have been through a state of hibernation. Your transition from the futures to the challengers' tour took a longer time. This probably has been a problem with most other Indians who usually do very well in the ITF Futures. What do you think is the reason behind this?
To be honest, there are quite a few reasons. Primarily, we do not have enough tournaments in India. And we do not have enough competition, to begin with. When you are only competing with other Indians and you don't realize what the tour level is, and then when you eventually go abroad and find yourselves in the deep end of the sea. So it takes a while to make that transition.
It's not that we are not capable of playing at that level. It's just that we lack a system but not the potential. Because you can see that we are successful in other sports right now, like Badminton, which is also a very physical sport. So, clearly, it can be done.
Like other tennis players have been saying, be it Somdev or Yuki, we need the changes in the grassroots'-level because that is what will create champions. Because you need to do the right thing from Day 1 and the chances of you making it after 20 or later are significantly lesser.
Prajnesh vs Yibing Wu in the Davis Cup tie in April, 2018.
Q) How has been your life on tour so far? What are some of the best experiences that you have had? How is your bond with the other players on tour and Indian compatriots?
I dunno. I am enjoying the Tour. I have been injury-free for the last couple of years (touchwood!). I am getting to play the full schedule of over 25 tournaments per year. I dunno, I'm really enjoying it!
Over time I have made friends on the circuit. Initially, when I was playing, I didn't even know whom to ask for being a practice-partner, unless there were fellow Indians. But now I know most of the players who are in the circuit, sort of more familiar.
Best experience: there is nothing to compete with the Davis Cup for me. Playing for your country, that team-spirit is itself exhilarating, which you don't get to feel on tour. Then, probably making the debut in the qualifiers of the previous two Slams was amazing, even though I couldn't do that well.
I am very close to most of the Indian guys traveling on the circuit and share a good relationship with most of them.
Q) How did you decide on going to the college in the US? What were the factors that you considered? What are the pros and cons?
I didn't have any plans of going to a college. I got injured for a little while and was doubtful if I will be able to compete again professionally, and decided that if I need some time then playing the college tennis is the best option. Many colleges approached me and eventually, I chose Tennessee.
I felt that I still had the potential to play at the highest level. I didn't have any timeline in my mind back then. And after one year I felt like I was ready to go. Unfortunately, I got injured again for about 3-4 years, I barely played. In hindsight, that could have gone better.
Playing college tennis definitely helps financially, lessens your burden mentally and physically. You get your education as well. It also depends on which college you go to. There are few guys who have done it outright at the highest level without going through the college route. If you are doing well and rising faster already, then you should continue playing professionally. Again, everything depends on what you want and stuff.
Image courtesy: Alexander Waske Tennis Academy.
Q) You are one of the most talented players to have come out of India but injuries have always held back your progress. What is causing the various injuries and how has your journey been with them?
I had a few minor injuries when I was younger. I did have some setbacks but nothing too bad. But the major injury after college was very difficult. I couldn't get the exact clinical diagnosis. I went to a lot of experts but they couldn't give me a clear answer. It never got fixed and took me a very long time. Eventually, I found a method to get rid of it.
Q) You are one of the few Indian players who has consistently done well on the European Clay circuit. Is Clay your strength? How has your stints in Spain / Germany (Schuttler-Waske) impacted your game?
Yeah, I am pretty good on clay because I trained a lot on clay back when I was 16-17, in Spain. I can generate more power and spin on my forehand. So, that could be the main reason. Other factors that make you a better clay-courter include your fitness and patience to play the longer and slower rallies. But I still feel that I am slightly better on hard. But I have the potential to be good on clay if I work on it enough, as I feel I have the set up to be a clay courter if I work on certain aspects.
I have been working with the coach, Bastian Suwanprateep, for a very long time in Schuttler-Waske. He has always been there to support me from the very beginning. He has fixed many issues associated with my game. All the coaches there know what it takes to make to the bigger stages. Alex himself was a top 100 player. I am very grateful for all the help and valuable advises, the structure and the direction, that they all have put me in.
Prajnesh won the ITF Futures title in Denmark in 2013. Image courtesy: Brit Sørensen.
Q) Any changes in your game that you wish you'd have done during your formative years, you think would have been more ideal?
Ah! I don't know. I tried as hard as I could to make it very successful aiming to be like someone in the top 10 or 20 in the world. Hardly did I realize that time that it would cause me such injuries. But, if I had to do it again, I'd do the exact same thing! Because I was very driven by passion and was not ready to slow down.
Q) How different is it to play the guys like Baghdatis (as in IPTL) or Istomin (as in AO-WC-POs)? Can we expect more Indians to beat these big guys in the coming years?
Of course! We now have Ramkumar doing very well. We also have Yuki in the top 85 after so many injury-struck seasons. That guy plays some amazing tennis, he's got such amazing skills! Ram is such a fighter and is in top 120 now. He's pretty young as well. I think these guys are already doing so well and will just get better. There's no reason for them not to.
As for the rest of the Indians: when somebody does it and breaks the mold and tells that it is possible, then others will believe that they can achieve it with grit and determination too. It just sets a path for all upcoming players.
Q) Tennis-In-India v/s Tennis-Elsewhere? What are your thoughts? Any changes that you would like to be implemented, if at all?
It would be just about finding ways to organize a lot of tournaments. Have good quality tennis coaches and good fitness coaches in all the academies, which will just force the players to improve their standards. It will constantly keep getting better. It should be a holistic approach and not just one thing that needs to change in the way the system functions in India. Having the right structure and the personnel is more important than just the facilities, in my opinion.
Q) For a person who doesn't play doubles much, you seem to be having phenomenal results in doubles. Finals of a $150K Challenger and the Semis with Bala couple of weeks before that. These are some of the best doubles results we had in the last 2 months. What is the trick here?
It might be that my game is sort of suited to play doubles as well. I have a good serve and I can play very good from the baseline. Nowadays doubles has changed quite a bit because it is not really necessary that you have to volley really well to play doubles. Like the Lopez brothers play a lot from the back. So, I think the game has evolved. And if you have the right kind of partner who compliments your game, then it works. Again, as I'm a singles player, I can play from both the sides. But just because I did well doesn't mean that I'll become an extremely good doubles player. I will be playing doubles whenever I get the chance, but my main focus will always be singles.
Q) You have already made it to the Slam Qualifiers of USO and AO. What are the goals that you have set for the rest of this year?
Right now, I am in the 260s and am unsure if I'll make it to the French Open. (Interviewer interrupts to say that all Indian tennis fans hope that he does make it in the upcoming tournaments that he's scheduled to play in China) (Praj giggles) It's just that I didn't want to play too many futures. I want to be able to do well in the Challengers consistently. That is my goal. And for that, I need to keep improving, play with better intensity constantly. And I feel that when I start doing that, it'll get much better.
I don't have any set goals for the rankings. It's more of a process-goal that I want to be playing in a certain way and at a certain level. And if I get that, the results will follow. Maybe after the Davis Cup, I am playing a bit more aggressive, trying to keep the momentum going.
Q) What are your thoughts on the restructured ITF tour?
To be honest, I don't know. It's going to be tricky, I think. How difficult the Challengers are going to get? How many of the players in top 700 have won points playing ATP events, etc.? I don't know. It will be a little bit of an experiment next year. The idea clearly has come after putting in lots of thoughts, otherwise, they wouldn't be making a change. I guess we'll just have to wait and see next year. To me, I really hope I do well enough in the Challengers and don't have to worry about all that.
Few questions were asked after his maiden triumph in the ATP Challenger Tour.
Prajnesh and Safwat at Kunming Open.
Q) You have been much more dominating in this challenger win. For example, the comeback in the semis after the bagel. How amazing was that?
How was your preparation for the final, and what are the changes in your game this year that have catapulted your game to the next level?In the SFs, I lost 2 service breaks in the first set. But it's a best of 3 sets match so I knew I would have a good chance irrespective of the score in the first set.
With regards to the Finals, I prepared the same way as I for every other match the whole week. Nothing special. Regular recovery work. Came back from a set down there as well. Was a wonderful week indeed.
Maiden ATP Challenger $150k+H for Prajnesh!
Q) Now that you have qualified for RG, how do you feel to play for the first time there and how are you going to prepare for the grand event?
I have been working on playing with more aggression. It is paying off now. I feel good since I am coming off a big tournament win on clay. So it gives me a lot more confidence.
Q) With your current ranking now you should be able to play a few ATP250 Qualifiers too. Any plans on that? Will we get to see you often?
I will find the right mix of ATP 250's qualifying events and Challengers depending on how I do in the next couple of months.
Rapid Fire:
Favorite Food Rasam rice
Favorite Person My parents (can't think of one)
Favorite Movie Black Panther (now!)
Favorite Song Keeps switching
Celebrity Crush None
Favorite Tournament Wimbledon
Dream Mixed Doubles Partner Martina Hingis
Favorite City that you have never been to Amsterdam
Tags: prajnesh gunneswaran
http://sufyanibrahim.wordpress.com
I'm the extravagant highfalutin you are looking for.
Interview with Vijay Sundar Prashanth
Interview with Kyra Shroff


text:
2 SHOT AT CLUB; MAN FLEES
STEVE NICHOL Staff WriterSUN-SENTINEL
Shouts of "Praise the Lord" elevated on Sunday from behind the tinted glass, storefront home of the International Pentecostal City Mission Prayer Center.
Several hours earlier in the same Yachtman's Plaza parking lot at 1600 N. Federal Highway, shouts of a nonreligious variety were heard.
"Drop it and fall!" yelled a police officer to a man with a 9mm handgun outside the Pyramid night club.
The gunman, who wounded two other bar patrons in the parking lot, managed to elude authorities despite tripping, losing his gun and being hunted by police dogs, officials say.
Authorities say the shooting incident began as a fight within the Pyramid, a relatively new restaurant-bar-music establishment nestled between the Haitian Ebenezer Baptist congregation and the Pentecostal church.
Police described the suspect as a black man with dreadlocks. He fled in clothes he ripped off a neighborhood clothesline.
It is the first shooting incident involving the club, but not the first time police have been called to the scene.
Tenants of the Seaview Park mobile home community at the rear of the shopping center say they have called police numerous times to complain about loud music from the Pyramid _ and a musical establishment previously in that location.
"It shakes the windows terribly," said trailer park resident Nancy Calderon about the decibel levels.
"I think everybody up and down the line has called, one time or another," said John Abel, another Seaview tenant who has slept over at a friend's home on occasion because of the noise.
Police were on the scene as the shooting occurred, responding to a noise complaint.
Police Sgt. Tom Wallace said the Pyramid owner was issued a citation for violating city noise codes after he refused to lower the volume.
That was about 12:30 a.m.
Close to 2 a.m. on Sunday, as patrons began to leave due to the closing hour, a brawl that began inside the club spilled into the parking lot, Wallace said.
Daniel Sephes of Riviera Beach and Aaron Clay of Boynton Beach were each wounded in the leg as a result of three shots fired by the suspect, Wilson said.
Sephes was treated and released at Bethesda Memorial Hospital.
Clay received emergency room treatment and was also expected to be released on Sunday, said a nursing supervisor.
It was unclear where the shooter's third bullet landed.
Wilson said it was fortunate others were not struck.
"There were about 100 people in the parking lot at the time," Wilson said. "It is amazing nobody was seriously injured or killed."
Boynton Beach Police Sgt. Richard Root tried to get the shooter to drop his gun. Root shielded himself behind his police cruiser when the suspect raised the gun toward his direction, Wilson said.
The suspect, however, stumbled, lost his semi-automatic pistol and took off running, Wilson said. He eluded the subsequent hunt that included more than one police dog.
Calderon, the Seaview resident, said she was awake when she heard the shots fired and an officer calling for the suspect to stop. She said she plans to follow up with her complaints about the loud music, and to try to close the club.
"I'll do everything in my power. I'll call the city manager tomorrow," she said. "It was scary, very terrifying last night. It was frightening."
The door to the Pyramid was locked early Sunday. A telephone message for comment by the club was not returned. A call to the shopping center's leasing company also was not returned.

redpajama_set_name: RedPajamaCommonCrawl


text:
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "extensions/browser/guest_view/web_view/web_view_guest.h"

#include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/resource_request_details.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/media_stream_request.h"
#include "content/public/common/page_zoom.h"
#include "content/public/common/result_codes.h"
#include "content/public/common/stop_find_action.h"
#include "content/public/common/url_constants.h"
#include "extensions/browser/api/declarative/rules_registry_service.h"
#include "extensions/browser/api/extensions_api_client.h"
#include "extensions/browser/api/guest_view/web_view/web_view_internal_api.h"
#include "extensions/browser/api/web_request/web_request_api.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/guest_view/guest_view_event.h"
#include "extensions/browser/guest_view/guest_view_manager.h"
#include "extensions/browser/guest_view/web_view/web_view_constants.h"
#include "extensions/browser/guest_view/web_view/web_view_permission_helper.h"
#include "extensions/browser/guest_view/web_view/web_view_permission_types.h"
#include "extensions/browser/guest_view/web_view/web_view_renderer_state.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension_messages.h"
#include "extensions/common/guest_view/guest_view_constants.h"
#include "extensions/strings/grit/extensions_strings.h"
#include "ipc/ipc_message_macros.h"
#include "net/base/escape.h"
#include "net/base/net_errors.h"
#include "ui/base/models/simple_menu_model.h"
#include "url/url_constants.h"

using base::UserMetricsAction;
using content::RenderFrameHost;
using content::ResourceType;
using content::StoragePartition;
using content::WebContents;
using ui_zoom::ZoomController;

namespace extensions {

namespace {

// Returns storage partition removal mask from web_view clearData mask. Note
// that storage partition mask is a subset of webview's data removal mask.
uint32 GetStoragePartitionRemovalMask(uint32 web_view_removal_mask) {
  uint32 mask = 0;
  if (web_view_removal_mask & webview::WEB_VIEW_REMOVE_DATA_MASK_APPCACHE)
    mask |= StoragePartition::REMOVE_DATA_MASK_APPCACHE;
  if (web_view_removal_mask & webview::WEB_VIEW_REMOVE_DATA_MASK_COOKIES)
    mask |= StoragePartition::REMOVE_DATA_MASK_COOKIES;
  if (web_view_removal_mask & webview::WEB_VIEW_REMOVE_DATA_MASK_FILE_SYSTEMS)
    mask |= StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS;
  if (web_view_removal_mask & webview::WEB_VIEW_REMOVE_DATA_MASK_INDEXEDDB)
    mask |= StoragePartition::REMOVE_DATA_MASK_INDEXEDDB;
  if (web_view_removal_mask & webview::WEB_VIEW_REMOVE_DATA_MASK_LOCAL_STORAGE)
    mask |= StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE;
  if (web_view_removal_mask & webview::WEB_VIEW_REMOVE_DATA_MASK_WEBSQL)
    mask |= StoragePartition::REMOVE_DATA_MASK_WEBSQL;

  return mask;
}

std::string WindowOpenDispositionToString(
  WindowOpenDisposition window_open_disposition) {
  switch (window_open_disposition) {
    case IGNORE_ACTION:
      return "ignore";
    case SAVE_TO_DISK:
      return "save_to_disk";
    case CURRENT_TAB:
      return "current_tab";
    case NEW_BACKGROUND_TAB:
      return "new_background_tab";
    case NEW_FOREGROUND_TAB:
      return "new_foreground_tab";
    case NEW_WINDOW:
      return "new_window";
    case NEW_POPUP:
      return "new_popup";
    default:
      NOTREACHED() << "Unknown Window Open Disposition";
      return "ignore";
  }
}

static std::string TerminationStatusToString(base::TerminationStatus status) {
  switch (status) {
    case base::TERMINATION_STATUS_NORMAL_TERMINATION:
      return "normal";
    case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
    case base::TERMINATION_STATUS_STILL_RUNNING:
      return "abnormal";
    case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
      return "killed";
    case base::TERMINATION_STATUS_PROCESS_CRASHED:
      return "crashed";
    case base::TERMINATION_STATUS_MAX_ENUM:
      break;
  }
  NOTREACHED() << "Unknown Termination Status.";
  return "unknown";
}

std::string GetStoragePartitionIdFromSiteURL(const GURL& site_url) {
  const std::string& partition_id = site_url.query();
  bool persist_storage = site_url.path().find("persist") != std::string::npos;
  return (persist_storage ? webview::kPersistPrefix : "") + partition_id;
}

void ParsePartitionParam(const base::DictionaryValue& create_params,
                         std::string* storage_partition_id,
                         bool* persist_storage) {
  std::string partition_str;
  if (!create_params.GetString(webview::kStoragePartitionId, &partition_str)) {
    return;
  }

  // Since the "persist:" prefix is in ASCII, StartsWith will work fine on
  // UTF-8 encoded |partition_id|. If the prefix is a match, we can safely
  // remove the prefix without splicing in the middle of a multi-byte codepoint.
  // We can use the rest of the string as UTF-8 encoded one.
  if (StartsWithASCII(partition_str, "persist:", true)) {
    size_t index = partition_str.find(":");
    CHECK(index != std::string::npos);
    // It is safe to do index + 1, since we tested for the full prefix above.
    *storage_partition_id = partition_str.substr(index + 1);

    if (storage_partition_id->empty()) {
      // TODO(lazyboy): Better way to deal with this error.
      return;
    }
    *persist_storage = true;
  } else {
    *storage_partition_id = partition_str;
    *persist_storage = false;
  }
}

void RemoveWebViewEventListenersOnIOThread(
    void* profile,
    const std::string& extension_id,
    int embedder_process_id,
    int view_instance_id) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
  ExtensionWebRequestEventRouter::GetInstance()->RemoveWebViewEventListeners(
      profile,
      extension_id,
      embedder_process_id,
      view_instance_id);
}

double ConvertZoomLevelToZoomFactor(double zoom_level) {
  double zoom_factor = content::ZoomLevelToZoomFactor(zoom_level);
  // Because the conversion from zoom level to zoom factor isn't perfect, the
  // resulting zoom factor is rounded to the nearest 6th decimal place.
  zoom_factor = round(zoom_factor * 1000000) / 1000000;
  return zoom_factor;
}

}  // namespace

// static
GuestViewBase* WebViewGuest::Create(content::WebContents* owner_web_contents) {
  return new WebViewGuest(owner_web_contents);
}

// static
bool WebViewGuest::GetGuestPartitionConfigForSite(
    const GURL& site,
    std::string* partition_domain,
    std::string* partition_name,
    bool* in_memory) {
  if (!site.SchemeIs(content::kGuestScheme))
    return false;

  // Since guest URLs are only used for packaged apps, there must be an app
  // id in the URL.
  CHECK(site.has_host());
  *partition_domain = site.host();
  // Since persistence is optional, the path must either be empty or the
  // literal string.
  *in_memory = (site.path() != "/persist");
  // The partition name is user supplied value, which we have encoded when the
  // URL was created, so it needs to be decoded.
  *partition_name =
      net::UnescapeURLComponent(site.query(), net::UnescapeRule::NORMAL);
  return true;
}

// static
const char WebViewGuest::Type[] = "webview";

using WebViewKey = std::pair<int, int>;
using WebViewKeyToIDMap = std::map<WebViewKey, int>;
static base::LazyInstance<WebViewKeyToIDMap> web_view_key_to_id_map =
    LAZY_INSTANCE_INITIALIZER;

// static
int WebViewGuest::GetOrGenerateRulesRegistryID(
    int embedder_process_id,
    int webview_instance_id) {
  bool is_web_view = embedder_process_id && webview_instance_id;
  if (!is_web_view)
    return RulesRegistryService::kDefaultRulesRegistryID;

  WebViewKey key = std::make_pair(embedder_process_id, webview_instance_id);
  auto it = web_view_key_to_id_map.Get().find(key);
  if (it != web_view_key_to_id_map.Get().end())
    return it->second;

  auto rph = content::RenderProcessHost::FromID(embedder_process_id);
  int rules_registry_id =
      RulesRegistryService::Get(rph->GetBrowserContext())->
          GetNextRulesRegistryID();
  web_view_key_to_id_map.Get()[key] = rules_registry_id;
  return rules_registry_id;
}

// static
int WebViewGuest::GetViewInstanceId(WebContents* contents) {
  auto guest = FromWebContents(contents);
  if (!guest)
    return guestview::kInstanceIDNone;

  return guest->view_instance_id();
}

bool WebViewGuest::CanRunInDetachedState() const {
  return true;
}

void WebViewGuest::CreateWebContents(
    const base::DictionaryValue& create_params,
    const WebContentsCreatedCallback& callback) {
  content::RenderProcessHost* owner_render_process_host =
      owner_web_contents()->GetRenderProcessHost();
  std::string storage_partition_id;
  bool persist_storage = false;
  ParsePartitionParam(create_params, &storage_partition_id, &persist_storage);
  // Validate that the partition id coming from the renderer is valid UTF-8,
  // since we depend on this in other parts of the code, such as FilePath
  // creation. If the validation fails, treat it as a bad message and kill the
  // renderer process.
  if (!base::IsStringUTF8(storage_partition_id)) {
    content::RecordAction(
        base::UserMetricsAction("BadMessageTerminate_BPGM"));
    owner_render_process_host->Shutdown(content::RESULT_CODE_KILLED_BAD_MESSAGE,
                                        false);
    callback.Run(nullptr);
    return;
  }
  std::string url_encoded_partition = net::EscapeQueryParamValue(
      storage_partition_id, false);
  std::string partition_domain = GetOwnerSiteURL().host();
  GURL guest_site(base::StringPrintf("%s://%s/%s?%s",
                                     content::kGuestScheme,
                                     partition_domain.c_str(),
                                     persist_storage ? "persist" : "",
                                     url_encoded_partition.c_str()));

  // If we already have a webview tag in the same app using the same storage
  // partition, we should use the same SiteInstance so the existing tag and
  // the new tag can script each other.
  auto guest_view_manager = GuestViewManager::FromBrowserContext(
      owner_render_process_host->GetBrowserContext());
  content::SiteInstance* guest_site_instance =
      guest_view_manager->GetGuestSiteInstance(guest_site);
  if (!guest_site_instance) {
    // Create the SiteInstance in a new BrowsingInstance, which will ensure
    // that webview tags are also not allowed to send messages across
    // different partitions.
    guest_site_instance = content::SiteInstance::CreateForURL(
        owner_render_process_host->GetBrowserContext(), guest_site);
  }
  WebContents::CreateParams params(
      owner_render_process_host->GetBrowserContext(),
      guest_site_instance);
  params.guest_delegate = this;
  callback.Run(WebContents::Create(params));
}

void WebViewGuest::DidAttachToEmbedder() {
  ApplyAttributes(*attach_params());
}

void WebViewGuest::DidDropLink(const GURL& url) {
  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
  args->SetString(guestview::kUrl, url.spec());
  DispatchEventToView(
      new GuestViewEvent(webview::kEventDropLink, args.Pass()));
}

void WebViewGuest::DidInitialize(const base::DictionaryValue& create_params) {
  script_executor_.reset(
      new ScriptExecutor(web_contents(), &script_observers_));

  notification_registrar_.Add(this,
                              content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
                              content::Source<WebContents>(web_contents()));

  notification_registrar_.Add(this,
                              content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT,
                              content::Source<WebContents>(web_contents()));

  if (web_view_guest_delegate_)
    web_view_guest_delegate_->OnDidInitialize();
  AttachWebViewHelpers(web_contents());

  rules_registry_id_ = GetOrGenerateRulesRegistryID(
      owner_web_contents()->GetRenderProcessHost()->GetID(),
      view_instance_id());

  // We must install the mapping from guests to WebViews prior to resuming
  // suspended resource loads so that the WebRequest API will catch resource
  // requests.
  PushWebViewStateToIOThread();

  ApplyAttributes(create_params);
}

void WebViewGuest::AttachWebViewHelpers(WebContents* contents) {
  if (web_view_guest_delegate_)
    web_view_guest_delegate_->OnAttachWebViewHelpers(contents);
  web_view_permission_helper_.reset(new WebViewPermissionHelper(this));
}

void WebViewGuest::ClearDataInternal(base::Time remove_since,
                                     uint32 removal_mask,
                                     const base::Closure& callback) {
  uint32 storage_partition_removal_mask =
      GetStoragePartitionRemovalMask(removal_mask);
  if (!storage_partition_removal_mask) {
    callback.Run();
    return;
  }
  content::StoragePartition* partition =
      content::BrowserContext::GetStoragePartition(
          web_contents()->GetBrowserContext(),
          web_contents()->GetSiteInstance());
  partition->ClearData(
      storage_partition_removal_mask,
      content::StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL, GURL(),
      content::StoragePartition::OriginMatcherFunction(), remove_since,
      base::Time::Now(), callback);
}

void WebViewGuest::GuestViewDidStopLoading() {
  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
  DispatchEventToView(
      new GuestViewEvent(webview::kEventLoadStop, args.Pass()));
}

void WebViewGuest::EmbedderFullscreenToggled(bool entered_fullscreen) {
  is_embedder_fullscreen_ = entered_fullscreen;
  // If the embedder has got out of fullscreen, we get out of fullscreen
  // mode as well.
  if (!entered_fullscreen)
    SetFullscreenState(false);
}

void WebViewGuest::EmbedderWillBeDestroyed() {
  // Clean up rules registries for the webview.
  RulesRegistryService::Get(browser_context())
      ->RemoveRulesRegistriesByID(rules_registry_id_);
  WebViewKey key(owner_web_contents()->GetRenderProcessHost()->GetID(),
                 view_instance_id());
  web_view_key_to_id_map.Get().erase(key);

  content::BrowserThread::PostTask(
      content::BrowserThread::IO,
      FROM_HERE,
      base::Bind(
          &RemoveWebViewEventListenersOnIOThread,
          browser_context(),
          owner_extension_id(),
          owner_web_contents()->GetRenderProcessHost()->GetID(),
          view_instance_id()));
}

const char* WebViewGuest::GetAPINamespace() const {
  return webview::kAPINamespace;
}

int WebViewGuest::GetTaskPrefix() const {
  return IDS_EXTENSION_TASK_MANAGER_WEBVIEW_TAG_PREFIX;
}

void WebViewGuest::GuestDestroyed() {
  // Clean up custom context menu items for this guest.
  if (web_view_guest_delegate_)
    web_view_guest_delegate_->OnGuestDestroyed();
  RemoveWebViewStateFromIOThread(web_contents());
}

void WebViewGuest::GuestReady() {
  // The guest RenderView should always live in an isolated guest process.
  CHECK(web_contents()->GetRenderProcessHost()->IsIsolatedGuest());
  Send(new ExtensionMsg_SetFrameName(web_contents()->GetRoutingID(), name_));

  // We don't want to accidentally set the opacity of an interstitial page.
  // WebContents::GetRenderWidgetHostView will return the RWHV of an
  // interstitial page if one is showing at this time. We only want opacity
  // to apply to web pages.
  if (allow_transparency_) {
    web_contents()->GetRenderViewHost()->GetView()->SetBackgroundColor(
        SK_ColorTRANSPARENT);
  } else {
    web_contents()
        ->GetRenderViewHost()
        ->GetView()
        ->SetBackgroundColorToDefault();
  }
}

void WebViewGuest::GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
                                                 const gfx::Size& new_size) {
  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
  args->SetInteger(webview::kOldHeight, old_size.height());
  args->SetInteger(webview::kOldWidth, old_size.width());
  args->SetInteger(webview::kNewHeight, new_size.height());
  args->SetInteger(webview::kNewWidth, new_size.width());
  DispatchEventToView(
      new GuestViewEvent(webview::kEventSizeChanged, args.Pass()));
}

bool WebViewGuest::IsAutoSizeSupported() const {
  return true;
}

bool WebViewGuest::IsDragAndDropEnabled() const {
  return true;
}

void WebViewGuest::GuestZoomChanged(double old_zoom_level,
                                    double new_zoom_level) {
  // Dispatch the zoomchange event.
  double old_zoom_factor = ConvertZoomLevelToZoomFactor(old_zoom_level);
  double new_zoom_factor = ConvertZoomLevelToZoomFactor(new_zoom_level);
  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
  args->SetDouble(webview::kOldZoomFactor, old_zoom_factor);
  args->SetDouble(webview::kNewZoomFactor, new_zoom_factor);
  DispatchEventToView(
      new GuestViewEvent(webview::kEventZoomChange, args.Pass()));
}

void WebViewGuest::WillDestroy() {
  if (!attached() && GetOpener())
    GetOpener()->pending_new_windows_.erase(this);
}

bool WebViewGuest::AddMessageToConsole(WebContents* source,
                                       int32 level,
                                       const base::string16& message,
                                       int32 line_no,
                                       const base::string16& source_id) {
  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
  // Log levels are from base/logging.h: LogSeverity.
  args->SetInteger(webview::kLevel, level);
  args->SetString(webview::kMessage, message);
  args->SetInteger(webview::kLine, line_no);
  args->SetString(webview::kSourceId, source_id);
  DispatchEventToView(
      new GuestViewEvent(webview::kEventConsoleMessage, args.Pass()));
  return true;
}

void WebViewGuest::CloseContents(WebContents* source) {
  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
  DispatchEventToView(
      new GuestViewEvent(webview::kEventClose, args.Pass()));
}

void WebViewGuest::FindReply(WebContents* source,
                             int request_id,
                             int number_of_matches,
                             const gfx::Rect& selection_rect,
                             int active_match_ordinal,
                             bool final_update) {
  find_helper_.FindReply(request_id,
                         number_of_matches,
                         selection_rect,
                         active_match_ordinal,
                         final_update);
}

double WebViewGuest::GetZoom() const {
  double zoom_level =
      ZoomController::FromWebContents(web_contents())->GetZoomLevel();
  return ConvertZoomLevelToZoomFactor(zoom_level);
}

ZoomController::ZoomMode WebViewGuest::GetZoomMode() {
  return ZoomController::FromWebContents(web_contents())->zoom_mode();
}

bool WebViewGuest::HandleContextMenu(
    const content::ContextMenuParams& params) {
  if (!web_view_guest_delegate_)
    return false;
  return web_view_guest_delegate_->HandleContextMenu(params);
}

void WebViewGuest::HandleKeyboardEvent(
    WebContents* source,
    const content::NativeWebKeyboardEvent& event) {
  if (HandleKeyboardShortcuts(event))
    return;

  GuestViewBase::HandleKeyboardEvent(source, event);
}

bool WebViewGuest::PreHandleGestureEvent(content::WebContents* source,
                                         const blink::WebGestureEvent& event) {
  return !allow_scaling_ && GuestViewBase::PreHandleGestureEvent(source, event);
}

void WebViewGuest::LoadProgressChanged(content::WebContents* source,
                                       double progress) {
  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
  args->SetString(guestview::kUrl, web_contents()->GetURL().spec());
  args->SetDouble(webview::kProgress, progress);
  DispatchEventToView(
      new GuestViewEvent(webview::kEventLoadProgress, args.Pass()));
}

void WebViewGuest::LoadAbort(bool is_top_level,
                             const GURL& url,
                             int error_code,
                             const std::string& error_type) {
  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
  args->SetBoolean(guestview::kIsTopLevel, is_top_level);
  args->SetString(guestview::kUrl, url.possibly_invalid_spec());
  args->SetInteger(guestview::kCode, error_code);
  args->SetString(guestview::kReason, error_type);
  DispatchEventToView(
      new GuestViewEvent(webview::kEventLoadAbort, args.Pass()));
}

void WebViewGuest::CreateNewGuestWebViewWindow(
    const content::OpenURLParams& params) {
  GuestViewManager* guest_manager =
      GuestViewManager::FromBrowserContext(browser_context());
  // Set the attach params to use the same partition as the opener.
  // We pull the partition information from the site's URL, which is of the
  // form guest://site/{persist}?{partition_name}.
  const GURL& site_url = web_contents()->GetSiteInstance()->GetSiteURL();
  const std::string storage_partition_id =
      GetStoragePartitionIdFromSiteURL(site_url);
  base::DictionaryValue create_params;
  create_params.SetString(webview::kStoragePartitionId, storage_partition_id);

  guest_manager->CreateGuest(WebViewGuest::Type,
                             embedder_web_contents(),
                             create_params,
                             base::Bind(&WebViewGuest::NewGuestWebViewCallback,
                                        weak_ptr_factory_.GetWeakPtr(),
                                        params));
}

void WebViewGuest::NewGuestWebViewCallback(
    const content::OpenURLParams& params,
    content::WebContents* guest_web_contents) {
  WebViewGuest* new_guest = WebViewGuest::FromWebContents(guest_web_contents);
  new_guest->SetOpener(this);

  // Take ownership of |new_guest|.
  pending_new_windows_.insert(
      std::make_pair(new_guest, NewWindowInfo(params.url, std::string())));

  // Request permission to show the new window.
  RequestNewWindowPermission(params.disposition,
                             gfx::Rect(),
                             params.user_gesture,
                             new_guest->web_contents());
}

// TODO(fsamuel): Find a reliable way to test the 'responsive' and
// 'unresponsive' events.
void WebViewGuest::RendererResponsive(content::WebContents* source) {
  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
  args->SetInteger(webview::kProcessId,
                   web_contents()->GetRenderProcessHost()->GetID());
  DispatchEventToView(
      new GuestViewEvent(webview::kEventResponsive, args.Pass()));
}

void WebViewGuest::RendererUnresponsive(content::WebContents* source) {
  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
  args->SetInteger(webview::kProcessId,
                   web_contents()->GetRenderProcessHost()->GetID());
  DispatchEventToView(
      new GuestViewEvent(webview::kEventUnresponsive, args.Pass()));
}

void WebViewGuest::Observe(int type,
                           const content::NotificationSource& source,
                           const content::NotificationDetails& details) {
  switch (type) {
    case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME: {
      DCHECK_EQ(content::Source<WebContents>(source).ptr(), web_contents());
      if (content::Source<WebContents>(source).ptr() == web_contents())
        LoadHandlerCalled();
      break;
    }
    case content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT: {
      DCHECK_EQ(content::Source<WebContents>(source).ptr(), web_contents());
      content::ResourceRedirectDetails* resource_redirect_details =
          content::Details<content::ResourceRedirectDetails>(details).ptr();
      bool is_top_level = resource_redirect_details->resource_type ==
                          content::RESOURCE_TYPE_MAIN_FRAME;
      LoadRedirect(resource_redirect_details->url,
                   resource_redirect_details->new_url,
                   is_top_level);
      break;
    }
    default:
      NOTREACHED() << "Unexpected notification sent.";
      break;
  }
}

void WebViewGuest::StartFindInternal(
    const base::string16& search_text,
    const blink::WebFindOptions& options,
    scoped_refptr<WebViewInternalFindFunction> find_function) {
  find_helper_.Find(web_contents(), search_text, options, find_function);
}

void WebViewGuest::StopFindingInternal(content::StopFindAction action) {
  find_helper_.CancelAllFindSessions();
  web_contents()->StopFinding(action);
}

bool WebViewGuest::Go(int relative_index) {
  content::NavigationController& controller = web_contents()->GetController();
  if (!controller.CanGoToOffset(relative_index))
    return false;

  controller.GoToOffset(relative_index);
  return true;
}

void WebViewGuest::Reload() {
  // TODO(fsamuel): Don't check for repost because we don't want to show
  // Chromium's repost warning. We might want to implement a separate API
  // for registering a callback if a repost is about to happen.
  web_contents()->GetController().Reload(false);
}

void WebViewGuest::SetUserAgentOverride(
    const std::string& user_agent_override) {
  is_overriding_user_agent_ = !user_agent_override.empty();
  if (is_overriding_user_agent_) {
    content::RecordAction(UserMetricsAction("WebView.Guest.OverrideUA"));
  }
  web_contents()->SetUserAgentOverride(user_agent_override);
}

void WebViewGuest::Stop() {
  web_contents()->Stop();
}

void WebViewGuest::Terminate() {
  content::RecordAction(UserMetricsAction("WebView.Guest.Terminate"));
  base::ProcessHandle process_handle =
      web_contents()->GetRenderProcessHost()->GetHandle();
  if (process_handle)
    web_contents()->GetRenderProcessHost()->Shutdown(
        content::RESULT_CODE_KILLED, false);
}

bool WebViewGuest::ClearData(base::Time remove_since,
                             uint32 removal_mask,
                             const base::Closure& callback) {
  content::RecordAction(UserMetricsAction("WebView.Guest.ClearData"));
  content::StoragePartition* partition =
      content::BrowserContext::GetStoragePartition(
          web_contents()->GetBrowserContext(),
          web_contents()->GetSiteInstance());

  if (!partition)
    return false;

  if (removal_mask & webview::WEB_VIEW_REMOVE_DATA_MASK_CACHE) {
    if (web_view_guest_delegate_) {
      // First clear http cache data and then clear the rest in
      // |ClearDataInternal|.
      web_view_guest_delegate_->ClearCache(
          remove_since, base::Bind(&WebViewGuest::ClearDataInternal,
                                   weak_ptr_factory_.GetWeakPtr(), remove_since,
                                   removal_mask, callback));
      return true;
    }
  }

  ClearDataInternal(remove_since, removal_mask, callback);
  return true;
}

WebViewGuest::WebViewGuest(content::WebContents* owner_web_contents)
    : GuestView<WebViewGuest>(owner_web_contents),
      rules_registry_id_(RulesRegistryService::kInvalidRulesRegistryID),
      find_helper_(this),
      is_overriding_user_agent_(false),
      allow_transparency_(false),
      javascript_dialog_helper_(this),
      allow_scaling_(false),
      is_guest_fullscreen_(false),
      is_embedder_fullscreen_(false),
      last_fullscreen_permission_was_allowed_by_embedder_(false),
      weak_ptr_factory_(this) {
  web_view_guest_delegate_.reset(
      ExtensionsAPIClient::Get()->CreateWebViewGuestDelegate(this));
}

WebViewGuest::~WebViewGuest() {
}

void WebViewGuest::DidCommitProvisionalLoadForFrame(
    content::RenderFrameHost* render_frame_host,
    const GURL& url,
    ui::PageTransition transition_type) {
  if (!render_frame_host->GetParent())
    src_ = url;
  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
  args->SetString(guestview::kUrl, url.spec());
  args->SetBoolean(guestview::kIsTopLevel, !render_frame_host->GetParent());
  args->SetString(webview::kInternalBaseURLForDataURL,
                  web_contents()
                      ->GetController()
                      .GetLastCommittedEntry()
                      ->GetBaseURLForDataURL()
                      .spec());
  args->SetInteger(webview::kInternalCurrentEntryIndex,
                   web_contents()->GetController().GetCurrentEntryIndex());
  args->SetInteger(webview::kInternalEntryCount,
                   web_contents()->GetController().GetEntryCount());
  args->SetInteger(webview::kInternalProcessId,
                   web_contents()->GetRenderProcessHost()->GetID());
  DispatchEventToView(
      new GuestViewEvent(webview::kEventLoadCommit, args.Pass()));

  find_helper_.CancelAllFindSessions();

  if (web_view_guest_delegate_) {
    web_view_guest_delegate_->OnDidCommitProvisionalLoadForFrame(
        !render_frame_host->GetParent());
  }
}

void WebViewGuest::DidFailProvisionalLoad(
    content::RenderFrameHost* render_frame_host,
    const GURL& validated_url,
    int error_code,
    const base::string16& error_description) {
  LoadAbort(!render_frame_host->GetParent(), validated_url, error_code,
            net::ErrorToShortString(error_code));
}

void WebViewGuest::DidStartProvisionalLoadForFrame(
    content::RenderFrameHost* render_frame_host,
    const GURL& validated_url,
    bool is_error_page,
    bool is_iframe_srcdoc) {
  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
  args->SetString(guestview::kUrl, validated_url.spec());
  args->SetBoolean(guestview::kIsTopLevel, !render_frame_host->GetParent());
  DispatchEventToView(
      new GuestViewEvent(webview::kEventLoadStart, args.Pass()));
}

void WebViewGuest::DocumentLoadedInFrame(
    content::RenderFrameHost* render_frame_host) {
  if (web_view_guest_delegate_)
    web_view_guest_delegate_->OnDocumentLoadedInFrame(render_frame_host);
}

void WebViewGuest::RenderProcessGone(base::TerminationStatus status) {
  // Cancel all find sessions in progress.
  find_helper_.CancelAllFindSessions();

  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
  args->SetInteger(webview::kProcessId,
                   web_contents()->GetRenderProcessHost()->GetID());
  args->SetString(webview::kReason, TerminationStatusToString(status));
  DispatchEventToView(
      new GuestViewEvent(webview::kEventExit, args.Pass()));
}

void WebViewGuest::UserAgentOverrideSet(const std::string& user_agent) {
  content::NavigationController& controller = web_contents()->GetController();
  content::NavigationEntry* entry = controller.GetVisibleEntry();
  if (!entry)
    return;
  entry->SetIsOverridingUserAgent(!user_agent.empty());
  web_contents()->GetController().Reload(false);
}

void WebViewGuest::FrameNameChanged(RenderFrameHost* render_frame_host,
                                    const std::string& name) {
  if (render_frame_host->GetParent())
    return;

  if (name_ == name)
    return;

  ReportFrameNameChange(name);
}

void WebViewGuest::ReportFrameNameChange(const std::string& name) {
  name_ = name;
  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
  args->SetString(webview::kName, name);
  DispatchEventToView(
      new GuestViewEvent(webview::kEventFrameNameChanged, args.Pass()));
}

void WebViewGuest::LoadHandlerCalled() {
  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
  DispatchEventToView(
      new GuestViewEvent(webview::kEventContentLoad, args.Pass()));
}

void WebViewGuest::LoadRedirect(const GURL& old_url,
                                const GURL& new_url,
                                bool is_top_level) {
  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
  args->SetBoolean(guestview::kIsTopLevel, is_top_level);
  args->SetString(webview::kNewURL, new_url.spec());
  args->SetString(webview::kOldURL, old_url.spec());
  DispatchEventToView(
      new GuestViewEvent(webview::kEventLoadRedirect, args.Pass()));
}

void WebViewGuest::PushWebViewStateToIOThread() {
  const GURL& site_url = web_contents()->GetSiteInstance()->GetSiteURL();
  std::string partition_domain;
  std::string partition_id;
  bool in_memory;
  if (!GetGuestPartitionConfigForSite(
          site_url, &partition_domain, &partition_id, &in_memory)) {
    NOTREACHED();
    return;
  }

  WebViewRendererState::WebViewInfo web_view_info;
  web_view_info.embedder_process_id =
      owner_web_contents()->GetRenderProcessHost()->GetID();
  web_view_info.instance_id = view_instance_id();
  web_view_info.partition_id = partition_id;
  web_view_info.owner_extension_id = owner_extension_id();
  web_view_info.rules_registry_id = rules_registry_id_;

  content::BrowserThread::PostTask(
      content::BrowserThread::IO,
      FROM_HERE,
      base::Bind(&WebViewRendererState::AddGuest,
                 base::Unretained(WebViewRendererState::GetInstance()),
                 web_contents()->GetRenderProcessHost()->GetID(),
                 web_contents()->GetRoutingID(),
                 web_view_info));
}

// static
void WebViewGuest::RemoveWebViewStateFromIOThread(
    WebContents* web_contents) {
  content::BrowserThread::PostTask(
      content::BrowserThread::IO, FROM_HERE,
      base::Bind(
          &WebViewRendererState::RemoveGuest,
          base::Unretained(WebViewRendererState::GetInstance()),
          web_contents->GetRenderProcessHost()->GetID(),
          web_contents->GetRoutingID()));
}

void WebViewGuest::RequestMediaAccessPermission(
    content::WebContents* source,
    const content::MediaStreamRequest& request,
    const content::MediaResponseCallback& callback) {
  web_view_permission_helper_->RequestMediaAccessPermission(source,
                                                            request,
                                                            callback);
}

bool WebViewGuest::CheckMediaAccessPermission(content::WebContents* source,
                                              const GURL& security_origin,
                                              content::MediaStreamType type) {
  return web_view_permission_helper_->CheckMediaAccessPermission(
      source, security_origin, type);
}

void WebViewGuest::CanDownload(
    content::RenderViewHost* render_view_host,
    const GURL& url,
    const std::string& request_method,
    const base::Callback<void(bool)>& callback) {
  web_view_permission_helper_->CanDownload(render_view_host,
                                           url,
                                           request_method,
                                           callback);
}

void WebViewGuest::RequestPointerLockPermission(
    bool user_gesture,
    bool last_unlocked_by_target,
    const base::Callback<void(bool)>& callback) {
  web_view_permission_helper_->RequestPointerLockPermission(
      user_gesture,
      last_unlocked_by_target,
      callback);
}

void WebViewGuest::WillAttachToEmbedder() {
  rules_registry_id_ = GetOrGenerateRulesRegistryID(
      owner_web_contents()->GetRenderProcessHost()->GetID(),
      view_instance_id());

  // We must install the mapping from guests to WebViews prior to resuming
  // suspended resource loads so that the WebRequest API will catch resource
  // requests.
  PushWebViewStateToIOThread();
}

content::JavaScriptDialogManager* WebViewGuest::GetJavaScriptDialogManager(
    WebContents* source) {
  return &javascript_dialog_helper_;
}

void WebViewGuest::NavigateGuest(const std::string& src,
                                 bool force_navigation) {
  if (src.empty())
    return;

  GURL url = ResolveURL(src);

  LoadURLWithParams(url, content::Referrer(),
                    ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
                    force_navigation);
}

bool WebViewGuest::HandleKeyboardShortcuts(
    const content::NativeWebKeyboardEvent& event) {
  // <webview> outside of Chrome Apps do not handle keyboard shortcuts.
  if (!in_extension())
    return false;

  if (event.type != blink::WebInputEvent::RawKeyDown)
    return false;

  // If the user hits the escape key without any modifiers then unlock the
  // mouse if necessary.
  if ((event.windowsKeyCode == ui::VKEY_ESCAPE) &&
      !(event.modifiers & blink::WebInputEvent::InputModifiers)) {
    return web_contents()->GotResponseToLockMouseRequest(false);
  }

#if defined(OS_MACOSX)
  if (event.modifiers != blink::WebInputEvent::MetaKey)
    return false;

  if (event.windowsKeyCode == ui::VKEY_OEM_4) {
    Go(-1);
    return true;
  }

  if (event.windowsKeyCode == ui::VKEY_OEM_6) {
    Go(1);
    return true;
  }
#else
  if (event.windowsKeyCode == ui::VKEY_BROWSER_BACK) {
    Go(-1);
    return true;
  }

  if (event.windowsKeyCode == ui::VKEY_BROWSER_FORWARD) {
    Go(1);
    return true;
  }
#endif

  return false;
}

void WebViewGuest::ApplyAttributes(const base::DictionaryValue& params) {
  std::string name;
  if (params.GetString(webview::kAttributeName, &name)) {
    // If the guest window's name is empty, then the WebView tag's name is
    // assigned. Otherwise, the guest window's name takes precedence over the
    // WebView tag's name.
    if (name_.empty())
      SetName(name);
  }
  if (attached())
    ReportFrameNameChange(name_);

  std::string user_agent_override;
  params.GetString(webview::kParameterUserAgentOverride, &user_agent_override);
  SetUserAgentOverride(user_agent_override);

  bool allow_transparency = false;
  if (params.GetBoolean(webview::kAttributeAllowTransparency,
      &allow_transparency)) {
    // We need to set the background opaque flag after navigation to ensure that
    // there is a RenderWidgetHostView available.
    SetAllowTransparency(allow_transparency);
  }

  bool allow_scaling = false;
  if (params.GetBoolean(webview::kAttributeAllowScaling, &allow_scaling))
    SetAllowScaling(allow_scaling);

  bool is_pending_new_window = false;
  if (GetOpener()) {
    // We need to do a navigation here if the target URL has changed between
    // the time the WebContents was created and the time it was attached.
    // We also need to do an initial navigation if a RenderView was never
    // created for the new window in cases where there is no referrer.
    auto it = GetOpener()->pending_new_windows_.find(this);
    if (it != GetOpener()->pending_new_windows_.end()) {
      const NewWindowInfo& new_window_info = it->second;
      if (new_window_info.changed || !web_contents()->HasOpener())
        NavigateGuest(new_window_info.url.spec(), false /* force_navigation */);

      // Once a new guest is attached to the DOM of the embedder page, then the
      // lifetime of the new guest is no longer managed by the opener guest.
      GetOpener()->pending_new_windows_.erase(this);

      is_pending_new_window = true;
    }
  }

  // Only read the src attribute if this is not a New Window API flow.
  if (!is_pending_new_window) {
    std::string src;
    params.GetString(webview::kAttributeSrc, &src);
    NavigateGuest(src, false /* force_navigation */);
  }
}

void WebViewGuest::ShowContextMenu(
    int request_id,
    const WebViewGuestDelegate::MenuItemVector* items) {
  if (web_view_guest_delegate_)
    web_view_guest_delegate_->OnShowContextMenu(request_id, items);
}

void WebViewGuest::SetName(const std::string& name) {
  if (name_ == name)
    return;
  name_ = name;

  Send(new ExtensionMsg_SetFrameName(routing_id(), name_));
}

void WebViewGuest::SetZoom(double zoom_factor) {
  auto zoom_controller = ZoomController::FromWebContents(web_contents());
  DCHECK(zoom_controller);
  double zoom_level = content::ZoomFactorToZoomLevel(zoom_factor);
  zoom_controller->SetZoomLevel(zoom_level);
}

void WebViewGuest::SetZoomMode(ZoomController::ZoomMode zoom_mode) {
  ZoomController::FromWebContents(web_contents())->SetZoomMode(zoom_mode);
}

void WebViewGuest::SetAllowTransparency(bool allow) {
  if (allow_transparency_ == allow)
    return;

  allow_transparency_ = allow;
  if (!web_contents()->GetRenderViewHost()->GetView())
    return;

  if (allow_transparency_) {
    web_contents()->GetRenderViewHost()->GetView()->SetBackgroundColor(
        SK_ColorTRANSPARENT);
  } else {
    web_contents()
        ->GetRenderViewHost()
        ->GetView()
        ->SetBackgroundColorToDefault();
  }
}

void WebViewGuest::SetAllowScaling(bool allow) {
  allow_scaling_ = allow;
}

bool WebViewGuest::LoadDataWithBaseURL(const std::string& data_url,
                                       const std::string& base_url,
                                       const std::string& virtual_url,
                                       std::string* error) {
  // Make GURLs from URLs.
  const GURL data_gurl = GURL(data_url);
  const GURL base_gurl = GURL(base_url);
  const GURL virtual_gurl = GURL(virtual_url);

  // Check that the provided URLs are valid.
  // |data_url| must be a valid data URL.
  if (!data_gurl.is_valid() || !data_gurl.SchemeIs(url::kDataScheme)) {
    base::SStringPrintf(
        error, webview::kAPILoadDataInvalidDataURL, data_url.c_str());
    return false;
  }
  // |base_url| must be a valid URL.
  if (!base_gurl.is_valid()) {
    base::SStringPrintf(
        error, webview::kAPILoadDataInvalidBaseURL, base_url.c_str());
    return false;
  }
  // |virtual_url| must be a valid URL.
  if (!virtual_gurl.is_valid()) {
    base::SStringPrintf(
        error, webview::kAPILoadDataInvalidVirtualURL, virtual_url.c_str());
    return false;
  }

  // Set up the parameters to load |data_url| with the specified |base_url|.
  content::NavigationController::LoadURLParams load_params(data_gurl);
  load_params.load_type = content::NavigationController::LOAD_TYPE_DATA;
  load_params.base_url_for_data_url = base_gurl;
  load_params.virtual_url_for_data_url = virtual_gurl;
  load_params.override_user_agent =
      content::NavigationController::UA_OVERRIDE_INHERIT;

  // Navigate to the data URL.
  GuestViewBase::LoadURLWithParams(load_params);

  return true;
}

void WebViewGuest::AddNewContents(content::WebContents* source,
                                  content::WebContents* new_contents,
                                  WindowOpenDisposition disposition,
                                  const gfx::Rect& initial_rect,
                                  bool user_gesture,
                                  bool* was_blocked) {
  if (was_blocked)
    *was_blocked = false;
  RequestNewWindowPermission(disposition,
                             initial_rect,
                             user_gesture,
                             new_contents);
}

content::WebContents* WebViewGuest::OpenURLFromTab(
    content::WebContents* source,
    const content::OpenURLParams& params) {
  // There are two use cases to consider from a security perspective:
  // 1.) Renderer-initiated navigation to chrome:// must always be blocked even
  //     if the <webview> is in WebUI. This is handled by
  //     WebViewGuest::LoadURLWithParams. WebViewGuest::NavigateGuest will also
  //     call LoadURLWithParams. CreateNewGuestWebViewWindow creates a new
  //     WebViewGuest which will call NavigateGuest in DidInitialize.
  // 2.) The Language Settings context menu item should always work, both in
  //     Chrome Apps and WebUI. This is a browser initiated request and so
  //     we pass it along to the embedder's WebContentsDelegate to get the
  //     browser to perform the action for the <webview>.
  if (!params.is_renderer_initiated) {
    if (!owner_web_contents()->GetDelegate())
      return nullptr;
    return owner_web_contents()->GetDelegate()->OpenURLFromTab(
        owner_web_contents(), params);
  }

  // If the guest wishes to navigate away prior to attachment then we save the
  // navigation to perform upon attachment. Navigation initializes a lot of
  // state that assumes an embedder exists, such as RenderWidgetHostViewGuest.
  // Navigation also resumes resource loading which we don't want to allow
  // until attachment.
  if (!attached()) {
    WebViewGuest* opener = GetOpener();
    auto it = opener->pending_new_windows_.find(this);
    if (it == opener->pending_new_windows_.end())
      return nullptr;
    const NewWindowInfo& info = it->second;
    NewWindowInfo new_window_info(params.url, info.name);
    new_window_info.changed = new_window_info.url != info.url;
    it->second = new_window_info;
    return nullptr;
  }

  // This code path is taken if RenderFrameImpl::DecidePolicyForNavigation
  // decides that a fork should happen. At the time of writing this comment,
  // the only way a well behaving guest could hit this code path is if it
  // navigates to a URL that's associated with the default search engine.
  // This list of URLs is generated by chrome::GetSearchURLs. Validity checks
  // are performed inside LoadURLWithParams such that if the guest attempts
  // to navigate to a URL that it is not allowed to navigate to, a 'loadabort'
  // event will fire in the embedder, and the guest will be navigated to
  // about:blank.
  if (params.disposition == CURRENT_TAB) {
    LoadURLWithParams(params.url, params.referrer, params.transition,
                      true /* force_navigation */);
    return web_contents();
  }

  // This code path is taken if Ctrl+Click, middle click or any of the
  // keyboard/mouse combinations are used to open a link in a new tab/window.
  // This code path is also taken on client-side redirects from about:blank.
  CreateNewGuestWebViewWindow(params);
  return nullptr;
}

void WebViewGuest::WebContentsCreated(WebContents* source_contents,
                                      int opener_render_frame_id,
                                      const base::string16& frame_name,
                                      const GURL& target_url,
                                      content::WebContents* new_contents) {
  auto guest = WebViewGuest::FromWebContents(new_contents);
  CHECK(guest);
  guest->SetOpener(this);
  std::string guest_name = base::UTF16ToUTF8(frame_name);
  guest->name_ = guest_name;
  pending_new_windows_.insert(
      std::make_pair(guest, NewWindowInfo(target_url, guest_name)));
}

void WebViewGuest::EnterFullscreenModeForTab(content::WebContents* web_contents,
                                             const GURL& origin) {
  // Ask the embedder for permission.
  base::DictionaryValue request_info;
  request_info.SetString(webview::kOrigin, origin.spec());
  web_view_permission_helper_->RequestPermission(
      WEB_VIEW_PERMISSION_TYPE_FULLSCREEN, request_info,
      base::Bind(&WebViewGuest::OnFullscreenPermissionDecided,
                 weak_ptr_factory_.GetWeakPtr()),
      false /* allowed_by_default */);

  // TODO(lazyboy): Right now the guest immediately goes fullscreen within its
  // bounds. If the embedder denies the permission then we will see a flicker.
  // Once we have the ability to "cancel" a renderer/ fullscreen request:
  // http://crbug.com/466854 this won't be necessary and we should be
  // Calling SetFullscreenState(true) once the embedder allowed the request.
  // Otherwise we would cancel renderer/ fullscreen if the embedder denied.
  SetFullscreenState(true);
}

void WebViewGuest::ExitFullscreenModeForTab(
    content::WebContents* web_contents) {
  SetFullscreenState(false);
}

bool WebViewGuest::IsFullscreenForTabOrPending(
    const content::WebContents* web_contents) const {
  return is_guest_fullscreen_;
}

void WebViewGuest::LoadURLWithParams(const GURL& url,
                                     const content::Referrer& referrer,
                                     ui::PageTransition transition_type,
                                     bool force_navigation) {
  // Do not allow navigating a guest to schemes other than known safe schemes.
  // This will block the embedder trying to load unwanted schemes, e.g.
  // chrome://.
  bool scheme_is_blocked =
      (!content::ChildProcessSecurityPolicy::GetInstance()->IsWebSafeScheme(
           url.scheme()) &&
       !url.SchemeIs(url::kAboutScheme)) ||
      url.SchemeIs(url::kJavaScriptScheme);
  if (scheme_is_blocked || !url.is_valid()) {
    LoadAbort(true /* is_top_level */, url, net::ERR_ABORTED,
              net::ErrorToShortString(net::ERR_ABORTED));
    NavigateGuest(url::kAboutBlankURL, true /* force_navigation */);
    return;
  }

  if (!force_navigation && (src_ == url))
    return;

  GURL validated_url(url);
  web_contents()->GetRenderProcessHost()->FilterURL(false, &validated_url);
  // As guests do not swap processes on navigation, only navigations to
  // normal web URLs are supported.  No protocol handlers are installed for
  // other schemes (e.g., WebUI or extensions), and no permissions or bindings
  // can be granted to the guest process.
  content::NavigationController::LoadURLParams load_url_params(validated_url);
  load_url_params.referrer = referrer;
  load_url_params.transition_type = transition_type;
  load_url_params.extra_headers = std::string();
  if (is_overriding_user_agent_) {
    load_url_params.override_user_agent =
        content::NavigationController::UA_OVERRIDE_TRUE;
  }
  GuestViewBase::LoadURLWithParams(load_url_params);

  src_ = validated_url;
}

void WebViewGuest::RequestNewWindowPermission(
    WindowOpenDisposition disposition,
    const gfx::Rect& initial_bounds,
    bool user_gesture,
    content::WebContents* new_contents) {
  auto guest = WebViewGuest::FromWebContents(new_contents);
  if (!guest)
    return;
  auto it = pending_new_windows_.find(guest);
  if (it == pending_new_windows_.end())
    return;
  const NewWindowInfo& new_window_info = it->second;

  // Retrieve the opener partition info if we have it.
  const GURL& site_url = new_contents->GetSiteInstance()->GetSiteURL();
  std::string storage_partition_id = GetStoragePartitionIdFromSiteURL(site_url);

  base::DictionaryValue request_info;
  request_info.SetInteger(webview::kInitialHeight, initial_bounds.height());
  request_info.SetInteger(webview::kInitialWidth, initial_bounds.width());
  request_info.Set(webview::kTargetURL,
                   new base::StringValue(new_window_info.url.spec()));
  request_info.Set(webview::kName, new base::StringValue(new_window_info.name));
  request_info.SetInteger(webview::kWindowID, guest->guest_instance_id());
  // We pass in partition info so that window-s created through newwindow
  // API can use it to set their partition attribute.
  request_info.Set(webview::kStoragePartitionId,
                   new base::StringValue(storage_partition_id));
  request_info.Set(
      webview::kWindowOpenDisposition,
      new base::StringValue(WindowOpenDispositionToString(disposition)));

  web_view_permission_helper_->
      RequestPermission(WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW,
                        request_info,
                        base::Bind(&WebViewGuest::OnWebViewNewWindowResponse,
                                   weak_ptr_factory_.GetWeakPtr(),
                                   guest->guest_instance_id()),
                                   false /* allowed_by_default */);
}

GURL WebViewGuest::ResolveURL(const std::string& src) {
  if (!in_extension())
    return GURL(src);

  GURL default_url(base::StringPrintf("%s://%s/",
                                      kExtensionScheme,
                                      owner_extension_id().c_str()));
  return default_url.Resolve(src);
}

void WebViewGuest::OnWebViewNewWindowResponse(
    int new_window_instance_id,
    bool allow,
    const std::string& user_input) {
  auto guest =
      WebViewGuest::From(owner_web_contents()->GetRenderProcessHost()->GetID(),
                         new_window_instance_id);
  if (!guest)
    return;

  if (!allow)
    guest->Destroy();
}

void WebViewGuest::OnFullscreenPermissionDecided(
    bool allowed,
    const std::string& user_input) {
  last_fullscreen_permission_was_allowed_by_embedder_ = allowed;
  SetFullscreenState(allowed);
}

bool WebViewGuest::GuestMadeEmbedderFullscreen() const {
  return last_fullscreen_permission_was_allowed_by_embedder_ &&
         is_embedder_fullscreen_;
}

void WebViewGuest::SetFullscreenState(bool is_fullscreen) {
  if (is_fullscreen == is_guest_fullscreen_)
    return;

  bool was_fullscreen = is_guest_fullscreen_;
  is_guest_fullscreen_ = is_fullscreen;
  // If the embedder entered fullscreen because of us, it should exit fullscreen
  // when we exit fullscreen.
  if (was_fullscreen && GuestMadeEmbedderFullscreen()) {
    // Dispatch a message so we can call document.webkitCancelFullscreen()
    // on the embedder.
    scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
    DispatchEventToView(
        new GuestViewEvent(webview::kEventExitFullscreen, args.Pass()));
  }
  // Since we changed fullscreen state, sending a Resize message ensures that
  // renderer/ sees the change.
  web_contents()->GetRenderViewHost()->WasResized();
}

}  // namespace extensions

redpajama_set_name: RedPajamaGithub


Rio Silver Inc (CVE:RYO) reached a new 52-week low on Monday . The company traded as low as C$0.04 and last traded at C$0.04, with a volume of 27000 shares trading hands. The stock had previously closed at C$0.04.
The stock has a market cap of $1.64 million and a price-to-earnings ratio of -5.71.
TRADEMARK VIOLATION WARNING: This piece of content was originally reported by The Cerbat Gem and is the sole property of of The Cerbat Gem. If you are accessing this piece of content on another website, it was illegally copied and reposted in violation of international trademark & copyright laws. The original version of this piece of content can be accessed at https://www.thecerbatgem.com/2019/03/25/rio-silver-ryo-reaches-new-12-month-low-at-0-04.html.
Rio Silver Inc engages in the acquisition, evaluation, and development of mineral properties in the Americas, Canada, and Peru. The company primarily explores for precious and base metal deposits. It holds 100% interests in the Niñobamba silver and gold project covering an area of 4,490 hectares located in southeast of Lima in the Department of Ayacucho, Peru; and the Gerow Lake property, a base metal project located in northwestern Ontario, Canada.
Receive News & Ratings for Rio Silver Daily - Enter your email address below to receive a concise daily summary of the latest news and analysts' ratings for Rio Silver and related companies with MarketBeat.com's FREE daily email newsletter.


Action Force Monthly #15 was released in August 1989.
In the desert of an oil Emirate in the Gulf of Arabia, Falcon briefs a team of Action Force members. A Cobra armoured division have captured an oil terminal and it is strongly defended as they aim to restrict the supply of oil to cause sabotage. Falcon assigns Backstop to drive the Persuader spearheading the assault, Cross Country to head the H.A.V.O.C.s and Heavy Metal to provide cover with the Maulers. Falcon boards the Persuader and the convoy enters a long range battle.
At the terminal, two miles away, the commanding Crimson Guardsman is dismissive of the attack when he learns there are only ten units. Falcon is also privately unsure but notes that the real assault is elsewhere. In the empty pipeline Tunnel Rat leads a grumbling team consisting of Fast Draw, Mainframe, Hit & Run and Crazylegs. In the battlefield Roadblock and Cross-Country note how the Maggot guns are getting accurate and realise there is a laser target designator guiding them. They spot it - a Viper in a Trouble-Bubble and Roadblock uses his H.A.V.O.C. guns to shoot it down. Falcon uses the Persuader's main gun to destroy some Maggots to give Tunnel Rat's team more time. Inside the pipeline Tunnel Rat hears a noise and realises it isn't an explosion but oil!
A Rattler flies toward the Action Force convoy and Falcon orders the Maulers to get out of the approach. One is destroyed but a H.A.V.O.C. soon destroys the Rattler. Meanwhile Tunnel Rat's team emerge from the pipeline and sneak through the terminal. Inside a tower a squad of Techo-Vipers are preparing explosives to ignite the entire oil field and cripple the Gulf. Suddenly Tunnel Rat's team enter and capture the Techno-Vipers, but the latter say the timers on the explosives cannot be cancelled as they are computer controlled. Mainframe attempts the task.
The Crimson Guardsman is informed that contact with the demolitions team has been lost, so he orders two Maggots to investigate. They reach the tower where Fast Draw is waiting. He destroys them both with his backpack mounted missiles. Inside the tower Mainframe tells the others he has nearly done the task but the final stage with either deactivate or detonate the explosives. Tunnel Rat tells him to go ahead and Mainframe is successful.
Outside the Crimson Guardsman orders a retreat and the destruction of as much of the terminal as possible, but the Persuader destroys his Maggot. All of the Action Force team converge inside the terminal to report mission accomplished as air support arrives.
Snake-Eyes has been sent on a mission by Flint. He is dropped from plane to land on an uninhabited island off Sweden where he must obtain photographic evidence of a covert Cobra laser research facility. He is seen as he lands but overpowers the two Vipers who investigate. He makes his way across the island and discovers the laser which he photographs. His orders give him clearance to destroy it if possible, though such a move will make his escape near impossible. He removes his grenade belt when suddenly he is found by a group of Vipers. They demand his camera but he grabs his sword and slices through their guns. As more come he boards a Rattler. The newly arrived Vipers aim their guns when suddenly the grenades detonate nearby fuel drums. Snake-Eyes sets the controls for the Rattler to smash into the laser, creating an explosion that destroys both. He swims away from the island to be collected by Flint in a submarine.
Flint's orders to Snake-Eyes appear in dialogue boxes throughout the mission.
This issue contains an Intelligence Profile factfile on Hit & Run.
The letters page prints letters on a variety of subjects.
The issue also contains a competition to win one of ten Persuader toys.
This issue also credits Jenny O'Connor as "Managing Editor".
This was the final issue of the series.


The BOARD OF TRUSTEES and OFFICERS of the Corporation govern ICEC. The Board of Trustees is the highest authority of the corporation with the responsibility of overseeing the corporation affairs and ensuring the operations of the corporation are in line with its purpose.
The board of Trustees shall fill any vacancy, resulted from resignation or removal of a board member, from among the nominees, who will be nominated from among those who have shown adherence to the Corporation's purpose and its goals through years of active support of the Corporation. Selection of the person to fill the vacated position will be by a majority vote of the then Board of Trustees to a term of 3 years with no limitation on the number of terms the person may be elected to serve. The elected board member may become a permanent member of the Board of Trustees upon the completion of one full term and the unanimous consent of all then serving permanent members.
The Board of Trustees, in its discretion, appoints executive officers as it deems appropriate for the execution of the Center's programs. Members of Board of Trustees are eligible to serve as executive officers, if they are so appointed by the Board. The Board of Trustees may establish one or more Advisory Boards.
Click ICEC-Amended Bylaws -May15-2015 to view the full text of Governance (Bylaws).


text:
Faculty Home » Faculty » Conservatory » David Zerull
David Zerull
Position: Chair of Conservatory Academics Division; Professor, Music Education
Email: dzerull@su.edu
Teaching Area(s):
Conservatory Professional Highlights:
Dr. Zerull has published articles in The Instrumentalist, Music Educators Journal, Design for Arts in Education Magazine, and Arts Education Policy Review. Dr Zerull was a contributing author for the monograph On the Nature of Musical Experience, and authored the MENC publication Getting Started with High School Band. He was a contributor for Strategies for Teaching Beginning and Intermediate Band, and Strategies for Teaching High School Band also published by MENC.
Dr. Zerull has appeared as guest conductor of Honor Bands and All-County Bands in Georgia, Massachusetts, Pennsylvania, West Virginia, Delaware, and Virginia, as well as Area All-State Band in New York. Dr. Zerull has presented clinics at Colorado, Maryland, Pennsylvania, New Jersey, Ohio, and Virginia Music Educators Association In-services, and at the Midwest Band and Orchestra Clinic. Presentation topics have included "Improving Musicianship in the Ensemble", "Developing Understanding Using a Comprehensive Approach in Performance Ensemble Classes", "Effective Interpretation and Physical Gestures for Ensemble Conductors", and most recently "Teaching Musical Expression". Dr. Zerull presented "Reconsidering Conducting and Performing for a Changing Time" at the Northwestern University Center for the Study of Education and the Music Experience Twenty-fifth Anniversary symposium.
David S. Zerull joined the Conservatory faculty in 1990 after thirteen years of public and private school teaching in music education, including vocal music at Lutheran High School West (Rocky River, Ohio); elementary instrumental music as graduate assistant at Bowling Green in the Laboratory School Project; and Director of Bands and Orchestra at Northwest Senior High School, (Cincinnati, Ohio).
B.M., M.M., Bowling Green State University; Ph.D., Northwestern University


We've talked often about how this is a great time to be a Star Wars fan, and that fact just got reinforced with the announcement that no fewer than 20 new Star Wars books will be released in the build up to the the release of JJ Abrams' Star Wars: The Force Awakens.
The Force Awakens is an extraordinarily, heavily guarded storyline. To track it, a lot of top-secret meetings were happening up in San Francisco as we worked through this program," said Disney Publishing Vice President, Andrew Sugerman. "The partnership with the story group and the editorial team always had to be true to the sanctity of the film while making sure that we find these moments to introduce hints, clues, and puzzle pieces. Without revealing what those pieces are, it will just allow readers to speculate about the new film: What could a location mean, or what could a character mean?"
The details of the new books are still being kept a closely guarded secret, not least because many of them are still being written. But according to EW, who broke the news this morning, a handful of titles have been announced by Star Wars publishers. Star Wars: Aftermath, which may well bridge the gap between Episode VI and Episode VII has been announced by Del Rey, while Marvel Comics has announced two prequel series to Star Wars: The Force Awakens with one of them being told from the perspective of the iconic Star Wars droid, C-3PO.
In terms of writers, a few names have been released along with the titles of the pieces they are working on. Cecil Castellucci (Tin Star) is set to write a Princess Leia-helmed tale entitled Moving Target; Jason Fry (Darth Maul: Shadow Conspiracy) is writing the new Luke Skywalker story, The Weapon of a Jedi, while Greg Rucka will pen Smuggler's Run, a new Han Solo adventure which I personally hope will see him set that famous Kessel Run record.
If you're already getting sweaty palms at the prospect of having to read so much content in the few months that remain before Star Wars: The Force Awakens, don't panic. Not all of these titles will be full novels and the majority will be aimed at a younger audience with everything from short stories to sticker books being released in what has been touted as the Journey to The Force Awakens. Still, these new adventures (a sticker book can be an adventure) will all be considered official Star Wars canon, so there's never been a better time to start acting like the big kid you really are.
More than anything, this represents a further chance for Disney and LucasFilm to continue laying the foundations for their new expanded universe. Although the old Star Wars EU was officially wiped out last year, that's not to say that some of its more popular characters won't be forgotten. It's entirely likely that we'll get to see new chapters written into stories of characters like Revan, Plagueis and Mara Jade to name but a few. It just means that for those who were unable to keep up with the rapidly spun web that was the old EU, you now have a chance to get in on the ground floor of the new one.


The roles and responsibilities of a Property Management Company involve the management of personal or commercial property for their clients. Property management involves the processes, systems, and manpower required to manage the life cycle of all acquired property including acquisition, control, accountability, responsibility, maintenance, utilization, and disposition.
Property Management companies help their clients buy, sell, rent and lease their properties, residential or commercial for a professional brokerage fee. The company engages in advertising client's properties, select prospective candidates and draw up agreements, check on legalities and help their clients close the deal.
A property management company needs information first hand and before the competitor, to stay ahead of the game. WOKKITpro helps you identify properties at a click of a button and on a single platform that will enable you to reach out to your potential clients faster. It also has a repository of all real estate suppliers that will further enable you to manage the property.
Property Management companies have ready access to all classified advertisements specific to real estate vertical.
This feature greatly helps them understand Real Estate rentals, Land prices, Property Sale and Lease rentals area wise, thus offering critical business intelligence before they approach a new client who wants to buy, sell, rent OR lease.
This feature on WOKKITpro helps the Property Management Consultant align with builders to facilitate Buy Sell Rent & Lease for their clients.
The ADVERTISEMENTS feature greatly helps the Developers and Builders with critical business intelligence on how they should package their projects in terms of amenities and price to gain an edge over competition and increase profitability.
Using this feature which offers business intelligence, the Developers and builders can greatly optimise their marketing spends.
The Public Notice feature of WOKKITpro throws up Demand Notices, Auction Notices, and Lost document notices etc. through Survey number searches, Bank name searches, Property owner name searches, Village name searches, thus helping the developer minimize risk on his capital investment on any land parcel.
The Public Notice feature in the app helps Property Management companies access any public announcements with respect to Real Estate firms' financial assets & other legal standings.
This feature of WOKKITpro helps a Property Management company access Government Notifications.
The Property Management company, through a Survey number Search, can access any Government acquisition plan on land parcels involving Government infrastructure developments like Roads, Highways, Metro rail, Airports, Bridges, etc.
This feature thus becomes very useful for the Property Management Company in minimizing risk on their client's capital investments by understanding Government plans on acquisitions and various Government schemes.
Having ready access to Gazettes, which is an authorised legal document by the Government, the Property Management Company helps their clients sav a lot of time and money in case of litigation at a later date.
This unique feature helps Property Management companies have ready access to all relevant Government information with respect to any property.
Relevant Government information includes details of Sub-registrar's office, Guideline Value of land, Area classification, Collector, MLA, etc., thus facilitating seamless liaison with Government offices on behalf of their clients.This helps save valuable time and money on these activities.
WOKKITpro gives the Property Management Company access targeted PAN INDIA news specific to the Real Estate Industry Vertical.
Real Estate specific news is culled out from over 300 newspaper editions by our team in English and Tamil.
This comprehensive repository of industry specific news helps Property Management company keep themselves updated over a click of a button, thus saving them the laborious task of reading multiple newspapers through a lens on a daily basis.
This feature also gives Property Management company access to location specific news that affects their operations.
WOKKITpro allows you to choose the areas or locations that a Property Management company is interested in and feeds them with area specific News, Classifieds and Advertisements from other Developers, thus facilitating business intelligence for better planning and profitability.
This feature makes available to the Property Management Company all new projects which can be presented to their clients to buy, sell, rent OR lease.
WOKKITpro gives the Property Management company easy access to a comprehensive list of Traders, Suppliers and Service providers in the construction industry.
This helps Property Management companies choose the right vendor for various properties on behalf of their clients.
WOKKITpro's GET QUOTE feature helps the Property Management companies send request for proposals for building materials and services to the comprehensive community of vendors listed on our app.
The traders and the service providers respond and send quotes through the App.
This feature greatly helps Property Management companies save big on their client's procurement costs.
Ramaniyam Siddarth Building, 2nd Floor, No.45, 5th Cross Street, Kalaimagal Nagar, Ekadduthangal, Chennai – 600032. Tamil Nadu.


text:
Papers relating to Wallace Stevens and the Cummington PressCorrespondence with Wallace Stevens
Correspondence with Wallace Stevens
Bookmark:https://archiveshub.jisc.ac.uk/data/gb133-wst/wst/1
GB 133 WST/1
GB 133 1-106
This first series in the archive primarily charts the creation and publication of three of Stevens' major works by the Cummington Press through correspondence: Notes toward a supreme fiction which he wrote especially for the Press; Esthetique du mal which was initially printed in the Kenyon Review in 1944; and Three academic pieces, originally published in the Partisan Review in 1947.
These letters reveal a vast amount of information about Wallace Stevens as a published poet, the process of publishing and his other literary correspondents; the working practices of the Cummington Press; the involvement of Harry Duncan, Katharine Frazier and Paul Williams and their external involvement with craftsmen. While never once referred to directly, the Second World War also has a presence of its own within the correspondence.
The content of these letters present us with a strong image of Stevens as a poet with a very business-like approach and detail the attainment of copyright from Washington, cost breakdowns of print runs and distribution, payment transactions for purchases made by Stevens and acknowledgement of receipt. Stevens consistently makes a point of paying directly for any costs at his expense so as not to hinder the Press financially. We are also provided with details of Stevens' professional relationship with the Alfred A. Knopf publishing house, who Stevens had many obligations towards and did not want to upset by working with a different company.
The letters from Stevens are rich in examples of the preferences he had for ink and paper colour. Throughout the correspondence is an ongoing mission to locate the perfect shade of creamy-yellow paper that Stevens envisioned, especially for the final pressing of Notes. While Stevens is very clear about his expectations and wishes concerning layout and materials, it is soon made evident that he placed great faith in the Press to make the necessary final decisions. The employment of skilled designers referred to within the correspondence represents the contemporary trends of illustrated poetry, illuminated lettering and presentation containers, while drawing attention to the variety of craftsmen both Harry Duncan and Stevens were aware of and in touch with. Stevens himself was in touch with many literary writers and university academics of the time whom he discusses with Harry Duncan. Reference is made to Williams Carlos Williams, Marianne Moore and lecturers at Harvard University who Stevens asks for books to be sent to. Stevens also mentions discussing the cost of printing with the diarist and erotic novelist Anaï;s Nin, which shows the broad scope of his literary contacts.
Also worthy of note is what the correspondence doesn't reveal in its content. The Second World War continued and ended throughout the ten year period this correspondence spans, yet it is never mentioned in any of the letters.
This correspondence has been arranged into 106 items to represent the sequence of sending and receiving; some letters stand on their own, and others are linked to replies. They are arranged chronologically to reflect not only the course of sending and receiving, but also the development of Stevens' engagement with the Press. This arrangement also places them geographically as the Press relocates and Stevens stays rooted in Hartford. Further, the letters placed in chronological order show Stevens' ongoing business relationship with Alfred A. Knopf running parallel alongside the Cummington Press.