protected function _resolve()
    {
        $match = $this->_view_manager->head->getElementsBy('tag', 'scripts');
        if (empty($match)) {
            throw new Template_Invalid_Structure_Exception('scripts tag missing in head template');
        }
        $scripts = $match[0];
        $required = array('id', 'lat', 'lng');
        foreach ($required as $attr) {
            if ($this->{$attr} === null) {
                throw new Data_Insufficient_Exception($attr);
            }
        }
        $markers_js = '';
        if ($this->marker) {
            if ($this->mlat === null) {
                throw new Data_Insufficient_Exception('mlat');
            }
            if ($this->mlng === null) {
                throw new Data_Insufficient_Exception('mlng');
            }
            $marker_ids = explode(';', $this->marker);
            $marker_lats = explode(';', $this->mlat);
            $marker_lngs = explode(';', $this->mlng);
            $marker_icons = explode(';', $this->micon);
            if ($this->mtitle) {
                $marker_titles = explode($this->titles_separator, $this->mtitle);
            } else {
                $marker_titles = array();
            }
            if ($this->mopen) {
                $marker_open = explode(';', $this->mopen);
            } else {
                $marker_open = array();
            }
            $mcount = count($marker_ids);
            if ($mcount > count($marker_lats)) {
                throw new Data_Insufficient_Exception('mlat');
            }
            if ($mcount > count($marker_lngs)) {
                throw new Data_Insufficient_Exception('mlng');
            }
            $innerHTML_str = $this->setContentByString ? '.innerHTML' : '';
            for ($mi = 0; $mi < $mcount; ++$mi) {
                if ($marker_ids[$mi] !== '' && $marker_ids[$mi] != '#') {
                    $markers_js .= <<<EOT

\t\tvar contentElem{$mi} = document.getElementById("{$marker_ids[$mi]}").cloneNode(true);
\t\tvar infowindow{$mi} = new google.maps.InfoWindow({content: contentElem{$mi}{$innerHTML_str}});
EOT;
                }
                $markers_js .= <<<EOT

\t\tvar markerPos{$mi} = new google.maps.LatLng({$marker_lats[$mi]}, {$marker_lngs[$mi]});
EOT;
                if (array_key_exists($mi, $marker_icons)) {
                    $marker_icon_js = ", icon: '" . str_replace("'", "\\'", $marker_icons[$mi]) . "'";
                } else {
                    $marker_icon_js = '';
                }
                if (array_key_exists($mi, $marker_titles)) {
                    $marker_title_js = ", title: '{$marker_titles[$mi]}'";
                } else {
                    $marker_title_js = '';
                }
                $markers_js .= <<<EOT

\t\tvar marker{$mi} = new google.maps.Marker({position: markerPos{$mi}, map: map{$marker_icon_js}{$marker_title_js}});
EOT;
                if ($marker_ids[$mi] !== '' && $marker_ids[$mi] != '#') {
                    $markers_js .= <<<EOT

\t\tgoogle.maps.event.addListener(marker{$mi}, 'click', function() { infowindow{$mi}.open(map, marker{$mi}); });
EOT;
                    if (array_key_exists($mi, $marker_open) && $marker_open[$mi]) {
                        $markers_js .= <<<EOT

\t\tinfowindow{$mi}.open(map, marker{$mi});
EOT;
                    }
                }
            }
        }
        if ($this->navigationControl) {
            $navigationControl_js = <<<EOT

\t\t\tnavigationControl: true,
EOT;
            if ($this->navigationControl !== true) {
                $navigationControl_js .= <<<EOT

\t\t\tnavigationControlOptions: {style: google.maps.NavigationControlStyle.{$this->navigationControl}},
EOT;
            }
        } else {
            $navigationControl_js = <<<EOT

\t\t\tnavigationControl: false,
EOT;
        }
        if ($this->mapTypeControl) {
            $mapTypeControl_js = <<<EOT

\t\t\tmapTypeControl: true,
EOT;
            if ($this->mapTypeControl !== true) {
                $mapTypeControl_js .= <<<EOT

\t\t\tmapTypeControlOptions: {style: google.maps.MapTypeControlStyle.{$this->mapTypeControl}},
EOT;
            }
        } else {
            $mapTypeControl_js = <<<EOT

\t\t\tmapTypeControl: false,
EOT;
        }
        if ($this->scaleControl) {
            $scaleControl_js = <<<EOT

\t\t\tscaleControl: true,
EOT;
        } else {
            $scaleControl_js = <<<EOT

\t\t\tscaleControl: false,
EOT;
        }
        $init_js_src = <<<EOT

\tfunction initialize_googlemap_{$this->id}()
\t{
\t\tvar myLatlng = new google.maps.LatLng({$this->lat}, {$this->lng});
\t\tvar myOptions =
\t\t{
\t\t\tzoom: {$this->zoom},
\t\t\tcenter: myLatlng,{$navigationControl_js}{$mapTypeControl_js}{$scaleControl_js}
\t\t\tmapTypeId: google.maps.MapTypeId.{$this->type}
\t\t}
\t\tvar map = new google.maps.Map(document.getElementById("{$this->id}"), myOptions);{$markers_js}
\t}
\tgoogle.setOnLoadCallback(initialize_googlemap_{$this->id});

EOT;
        $init_js = new HTML_Javascript();
        $init_js->add(new HTML_Text($init_js_src));
        $sensor = $this->sensor ? 'true' : 'false';
        $scripts->addUnique(new HTML_JavaScript("http://www.google.com/jsapi?autoload=" . urlencode("{modules:[{name:\"maps\",version:3,other_params:\"sensor={$sensor}\"}]}")));
        $scripts->addUnique($init_js);
    }