//# 0 errors, 207 messages
//#
package net.sourceforge.pebble.permalink;
    //#latin1seopermalinkprovider.java:1:1: class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider

import net.sourceforge.pebble.api.permalink.PermalinkProvider;
import net.sourceforge.pebble.domain.*;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

/**
 * Generates permalinks based upon the blog entry title. This implementation
 * retains characters from the latin1 character by converting
 * them to suitable "url-friendly" counterparts.
 *
 * It also uses dashes instead of underscores for whitespace as this is
 * what Google recommends.

 * For titles without characters from the latin1 character set
 * the blog entry ID is used for the permalink instead.
 *
 * @author Mattias Reichel
 */
public class Latin1SeoPermalinkProvider implements PermalinkProvider {
    //#latin1seopermalinkprovider.java:24: method: void net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider()
    //#latin1seopermalinkprovider.java:24: end of method: void net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider()

    /** the regex used to check for a day request */
    private static final String DAY_PERMALINK_REGEX = "/\\d\\d\\d\\d/\\d\\d/\\d\\d";

    /** the regex used to check for a monthly blog request */
    private static final String MONTH_PERMALINK_REGEX = "/\\d\\d\\d\\d/\\d\\d";

    /** the regex used to check for a blog entry permalink */
    private static final String BLOG_ENTRY_PERMALINK_REGEX = "/[\\w-]*";

    /** the Blog associated with this provider instance */
    private Blog blog;

    /**
     * Gets the blog associated with this provider instance.
     *
     * @return  a Blog instance
     */
    public Blog getBlog() {
      return this.blog;
    //#latin1seopermalinkprovider.java:44: method: Blog net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.getBlog()
    //#input(Blog getBlog()): this
    //#input(Blog getBlog()): this.blog
    //#output(Blog getBlog()): return_value
    //#pre[2] (Blog getBlog()): init'ed(this.blog)
    //#post(Blog getBlog()): return_value == this.blog
    //#post(Blog getBlog()): init'ed(return_value)
    //#latin1seopermalinkprovider.java:44: end of method: Blog net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.getBlog()
    }

    /**
     * Sets the blog associated with this provider instance.
     *
     * @param blog    a Blog instance
     */
    public void setBlog(Blog blog) {
      this.blog = blog;
    //#latin1seopermalinkprovider.java:53: method: void net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.setBlog(Blog)
    //#input(void setBlog(Blog)): blog
    //#input(void setBlog(Blog)): this
    //#output(void setBlog(Blog)): this.blog
    //#post(void setBlog(Blog)): this.blog == blog
    //#post(void setBlog(Blog)): init'ed(this.blog)
    }
    //#latin1seopermalinkprovider.java:54: end of method: void net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.setBlog(Blog)

    /**
     * Gets the permalink for a blog entry.
     *
     * @return  a URI as a String
     */
    public synchronized String getPermalink(BlogEntry blogEntry) {
        if (blogEntry.getTitle() == null || blogEntry.getTitle().length() == 0) {
    //#latin1seopermalinkprovider.java:62: method: String net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.getPermalink(BlogEntry)
    //#latin1seopermalinkprovider.java:62: Warning: method not available
    //#    -- call on String net.sourceforge.pebble.domain.BlogEntry:getTitle()
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: String getPermalink(BlogEntry)
    //#    unanalyzed callee: String net.sourceforge.pebble.domain.BlogEntry:getTitle()
    //#input(String getPermalink(BlogEntry)): __Descendant_Table[net/sourceforge/pebble/permalink/Latin1SeoPermalinkProvider]
    //#input(String getPermalink(BlogEntry)): __Descendant_Table[others]
    //#input(String getPermalink(BlogEntry)): __Dispatch_Table.getBlog()Lnet/sourceforge/pebble/domain/Blog;
    //#input(String getPermalink(BlogEntry)): blogEntry
    //#input(String getPermalink(BlogEntry)): characterSubstitutions
    //#input(String getPermalink(BlogEntry)): this
    //#input(String getPermalink(BlogEntry)): this.__Tag
    //#input(String getPermalink(BlogEntry)): this.blog
    //#output(String getPermalink(BlogEntry)): return_value
    //#pre[1] (String getPermalink(BlogEntry)): blogEntry != null
    //#pre[3] (String getPermalink(BlogEntry)): (soft) this.__Tag == net/sourceforge/pebble/permalink/Latin1SeoPermalinkProvider
    //#pre[4] (String getPermalink(BlogEntry)): (soft) this.blog != null
    //#presumption(String getPermalink(BlogEntry)): java.util.List:get(...)@70 != null
    //#presumption(String getPermalink(BlogEntry)): java.util.List:indexOf(...)@68 - java.util.List:size(...)@68 in -4_294_967_296..6_442_450_942
    //#presumption(String getPermalink(BlogEntry)): java.util.List:size(...)@68 >= -2_147_483_647
    //#presumption(String getPermalink(BlogEntry)): net.sourceforge.pebble.domain.Blog:getBlogEntries(...)@66 != null
    //#presumption(String getPermalink(BlogEntry)): net.sourceforge.pebble.domain.BlogEntry:getTitle(...)@62 != null
    //#presumption(String getPermalink(BlogEntry)): net.sourceforge.pebble.domain.BlogEntry:getTitle(...)@71 != null
    //#presumption(String getPermalink(BlogEntry)): net.sourceforge.pebble.domain.BlogService:getBlogEntry(...)@70 != null
    //#post(String getPermalink(BlogEntry)): return_value != null
    //#unanalyzed(String getPermalink(BlogEntry)): Effects-of-calling:net.sourceforge.pebble.domain.BlogEntry:getTitle
    //#unanalyzed(String getPermalink(BlogEntry)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(String getPermalink(BlogEntry)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(String getPermalink(BlogEntry)): Effects-of-calling:net.sourceforge.pebble.domain.BlogEntry:getId
    //#unanalyzed(String getPermalink(BlogEntry)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(String getPermalink(BlogEntry)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(String getPermalink(BlogEntry)): Effects-of-calling:java.lang.String:toLowerCase
    //#unanalyzed(String getPermalink(BlogEntry)): Effects-of-calling:java.lang.String:replaceAll
    //#unanalyzed(String getPermalink(BlogEntry)): Effects-of-calling:java.util.HashMap:keySet
    //#unanalyzed(String getPermalink(BlogEntry)): Effects-of-calling:java.util.Set:iterator
    //#unanalyzed(String getPermalink(BlogEntry)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(String getPermalink(BlogEntry)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(String getPermalink(BlogEntry)): Effects-of-calling:java.util.HashMap:get
    //#test_vector(String getPermalink(BlogEntry)): java.lang.String:equals(...)@71: {0}, {1}
    //#test_vector(String getPermalink(BlogEntry)): java.lang.String:length(...)@62: {1..4_294_967_295}, {0}
    //#test_vector(String getPermalink(BlogEntry)): net.sourceforge.pebble.domain.BlogEntry:getTitle(...)@62: Addr_Set{null}, Inverse{null}
            return buildPermalink(blogEntry);
        } else {
            BlogService service = new BlogService();
    //#latin1seopermalinkprovider.java:65: Warning: method not available
    //#    -- call on void net.sourceforge.pebble.domain.BlogService()
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: String getPermalink(BlogEntry)
    //#    unanalyzed callee: void net.sourceforge.pebble.domain.BlogService()
            List entries = getBlog().getBlogEntries();
    //#latin1seopermalinkprovider.java:66: Warning: method not available
    //#    -- call on List net.sourceforge.pebble.domain.Blog:getBlogEntries()
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: String getPermalink(BlogEntry)
    //#    unanalyzed callee: List net.sourceforge.pebble.domain.Blog:getBlogEntries()
            int count = 0;
            for (int i = entries.size() - 1; i > entries.indexOf(blogEntry.getId()); i--) {
    //#latin1seopermalinkprovider.java:68: Warning: method not available
    //#    -- call on String net.sourceforge.pebble.domain.BlogEntry:getId()
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: String getPermalink(BlogEntry)
    //#    unanalyzed callee: String net.sourceforge.pebble.domain.BlogEntry:getId()
                try {
                    BlogEntry entry = service.getBlogEntry(getBlog(), "" + ((BlogEntry)entries.get(i)).getId());
    //#latin1seopermalinkprovider.java:70: Warning: method not available
    //#    -- call on String net.sourceforge.pebble.domain.BlogEntry:getId()
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: String getPermalink(BlogEntry)
    //#    unanalyzed callee: String net.sourceforge.pebble.domain.BlogEntry:getId()
    //#latin1seopermalinkprovider.java:70: Warning: method not available
    //#    -- call on BlogEntry net.sourceforge.pebble.domain.BlogService:getBlogEntry(Blog, String)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: String getPermalink(BlogEntry)
    //#    unanalyzed callee: BlogEntry net.sourceforge.pebble.domain.BlogService:getBlogEntry(Blog, String)
                    if (entry.getTitle().equals(blogEntry.getTitle())) {
    //#latin1seopermalinkprovider.java:71: Warning: method not available
    //#    -- call on String net.sourceforge.pebble.domain.BlogEntry:getTitle()
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: String getPermalink(BlogEntry)
    //#    unanalyzed callee: String net.sourceforge.pebble.domain.BlogEntry:getTitle()
                        count++;
                    }
                } catch (BlogServiceException e) {
                    // do nothing
                }
            }

            if (count == 1) {
                return buildPermalink(blogEntry);
            } else {
                return buildPermalink(blogEntry) + "_" + blogEntry.getId();
    //#latin1seopermalinkprovider.java:82: Warning: method not available
    //#    -- call on String net.sourceforge.pebble.domain.BlogEntry:getId()
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: String getPermalink(BlogEntry)
    //#    unanalyzed callee: String net.sourceforge.pebble.domain.BlogEntry:getId()
    //#latin1seopermalinkprovider.java:82: end of method: String net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.getPermalink(BlogEntry)
            }
        }
    }

    private String buildPermalink(BlogEntry blogEntry) {
        String title = blogEntry.getTitle();
    //#latin1seopermalinkprovider.java:88: method: String net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.buildPermalink(BlogEntry)
    //#latin1seopermalinkprovider.java:88: Warning: method not available
    //#    -- call on String net.sourceforge.pebble.domain.BlogEntry:getTitle()
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: String buildPermalink(BlogEntry)
    //#    unanalyzed callee: String net.sourceforge.pebble.domain.BlogEntry:getTitle()
    //#input(String buildPermalink(BlogEntry)): blogEntry
    //#input(String buildPermalink(BlogEntry)): characterSubstitutions
    //#output(String buildPermalink(BlogEntry)): return_value
    //#pre[1] (String buildPermalink(BlogEntry)): blogEntry != null
    //#post(String buildPermalink(BlogEntry)): return_value != null
    //#test_vector(String buildPermalink(BlogEntry)): java.lang.String:length(...)@104: {1..4_294_967_295}, {0}
    //#test_vector(String buildPermalink(BlogEntry)): java.lang.String:length(...)@89: {1..4_294_967_295}, {0}
    //#test_vector(String buildPermalink(BlogEntry)): java.util.Iterator:hasNext(...)@94: {1}, {0}
    //#test_vector(String buildPermalink(BlogEntry)): net.sourceforge.pebble.domain.BlogEntry:getTitle(...)@88: Addr_Set{null}, Inverse{null}
        if (title == null || title.length() == 0) {
            title = "" + blogEntry.getId();
    //#latin1seopermalinkprovider.java:90: Warning: method not available
    //#    -- call on String net.sourceforge.pebble.domain.BlogEntry:getId()
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: String buildPermalink(BlogEntry)
    //#    unanalyzed callee: String net.sourceforge.pebble.domain.BlogEntry:getId()
        } else {
            title = title.toLowerCase();
            title = title.replaceAll("[\\. ,;/\\\\_]", "-"); // Change whitespace and punctuation marks to dashes
            for(String search : characterSubstitutions.keySet()) {
                title = title.replaceAll(search, characterSubstitutions.get(search));
            }
            title = title.replaceAll("[^a-z0-9-]", "");
            title = title.replaceAll("-+", "-");
            title = title.replaceAll("^-*", "");
            title = title.replaceAll("-*$", "");
        }

        // if the title has been blanked out, use the blog entry instead
        if (title == null || title.length() == 0) {
    //#latin1seopermalinkprovider.java:104: Warning: test always goes same way
    //#    test predetermined because title != null
    //#    severity: LOW
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: String buildPermalink(BlogEntry)
    //#    from bb: bb_8
    //#    live edge: bb_8-->bb_9
    //#    tested vn: title == null
    //#    tested vn values: {0}
            title = "" + blogEntry.getId();
    //#latin1seopermalinkprovider.java:105: Warning: method not available
    //#    -- call on String net.sourceforge.pebble.domain.BlogEntry:getId()
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: String buildPermalink(BlogEntry)
    //#    unanalyzed callee: String net.sourceforge.pebble.domain.BlogEntry:getId()
        }

        return "/" + title;
    //#latin1seopermalinkprovider.java:108: end of method: String net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.buildPermalink(BlogEntry)
    }


    public boolean isBlogEntryPermalink(String uri) {
        if(uri != null) {
    //#latin1seopermalinkprovider.java:113: method: bool net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.isBlogEntryPermalink(String)
    //#input(bool isBlogEntryPermalink(String)): uri
    //#output(bool isBlogEntryPermalink(String)): return_value
    //#post(bool isBlogEntryPermalink(String)): init'ed(return_value)
    //#test_vector(bool isBlogEntryPermalink(String)): uri: Addr_Set{null}, Inverse{null}
            return uri.matches(BLOG_ENTRY_PERMALINK_REGEX);
        } else {
            return false;
    //#latin1seopermalinkprovider.java:116: end of method: bool net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.isBlogEntryPermalink(String)
        }
    }

    public BlogEntry getBlogEntry(String uri) {
        BlogService service = new BlogService();
    //#latin1seopermalinkprovider.java:121: method: BlogEntry net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.getBlogEntry(String)
    //#latin1seopermalinkprovider.java:121: Warning: method not available
    //#    -- call on void net.sourceforge.pebble.domain.BlogService()
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: BlogEntry getBlogEntry(String)
    //#    unanalyzed callee: void net.sourceforge.pebble.domain.BlogService()
    //#input(BlogEntry getBlogEntry(String)): __Descendant_Table[net/sourceforge/pebble/permalink/Latin1SeoPermalinkProvider]
    //#input(BlogEntry getBlogEntry(String)): __Descendant_Table[others]
    //#input(BlogEntry getBlogEntry(String)): __Dispatch_Table.getBlog()Lnet/sourceforge/pebble/domain/Blog;
    //#input(BlogEntry getBlogEntry(String)): this
    //#input(BlogEntry getBlogEntry(String)): this.__Tag
    //#input(BlogEntry getBlogEntry(String)): this.blog
    //#input(BlogEntry getBlogEntry(String)): uri
    //#output(BlogEntry getBlogEntry(String)): return_value
    //#pre[2] (BlogEntry getBlogEntry(String)): this.__Tag == net/sourceforge/pebble/permalink/Latin1SeoPermalinkProvider
    //#pre[3] (BlogEntry getBlogEntry(String)): this.blog != null
    //#presumption(BlogEntry getBlogEntry(String)): java.util.Iterator:next(...)@125 != null
    //#presumption(BlogEntry getBlogEntry(String)): net.sourceforge.pebble.domain.Blog:getBlogEntries(...)@122 != null
    //#presumption(BlogEntry getBlogEntry(String)): net.sourceforge.pebble.domain.BlogEntry:getLocalPermalink(...)@128 != null
    //#presumption(BlogEntry getBlogEntry(String)): net.sourceforge.pebble.domain.BlogService:getBlogEntry(...)@125 != null
    //#post(BlogEntry getBlogEntry(String)): init'ed(return_value)
    //#test_vector(BlogEntry getBlogEntry(String)): java.lang.String:endsWith(...)@128: {0}, {1}
    //#test_vector(BlogEntry getBlogEntry(String)): java.util.Iterator:hasNext(...)@123: {1}, {0}
        Iterator it = getBlog().getBlogEntries().iterator();
    //#latin1seopermalinkprovider.java:122: Warning: method not available
    //#    -- call on List net.sourceforge.pebble.domain.Blog:getBlogEntries()
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: BlogEntry getBlogEntry(String)
    //#    unanalyzed callee: List net.sourceforge.pebble.domain.Blog:getBlogEntries()
        while(it.hasNext()) {
            try {
                BlogEntry blogEntry = service.getBlogEntry(getBlog(), "" + ((BlogEntry)it.next()).getId());
    //#latin1seopermalinkprovider.java:125: Warning: method not available
    //#    -- call on String net.sourceforge.pebble.domain.BlogEntry:getId()
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: BlogEntry getBlogEntry(String)
    //#    unanalyzed callee: String net.sourceforge.pebble.domain.BlogEntry:getId()
    //#latin1seopermalinkprovider.java:125: Warning: method not available
    //#    -- call on BlogEntry net.sourceforge.pebble.domain.BlogService:getBlogEntry(Blog, String)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: BlogEntry getBlogEntry(String)
    //#    unanalyzed callee: BlogEntry net.sourceforge.pebble.domain.BlogService:getBlogEntry(Blog, String)
                // use the local permalink, just in case the entry has been aggregated
                // and an original permalink assigned
                if (blogEntry.getLocalPermalink().endsWith(uri)) {
    //#latin1seopermalinkprovider.java:128: Warning: method not available
    //#    -- call on String net.sourceforge.pebble.domain.BlogEntry:getLocalPermalink()
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: BlogEntry getBlogEntry(String)
    //#    unanalyzed callee: String net.sourceforge.pebble.domain.BlogEntry:getLocalPermalink()
                    return blogEntry;
                }
            } catch (BlogServiceException e) {
                // do nothing
            }
        }

        return null;
    //#latin1seopermalinkprovider.java:136: end of method: BlogEntry net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.getBlogEntry(String)
    }

    /**
     * Gets the permalink for a monthly blog.
     *
     * @param month a Month instance
     * @return a URI as a String
     */
    public String getPermalink(Month month) {
      SimpleDateFormat format = new SimpleDateFormat("'/'yyyy'/'MM");
    //#latin1seopermalinkprovider.java:146: method: String net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.getPermalink(Month)
    //#input(String getPermalink(Month)): month
    //#input(String getPermalink(Month)): this
    //#input(String getPermalink(Month)): this.blog
    //#output(String getPermalink(Month)): return_value
    //#pre[1] (String getPermalink(Month)): month != null
    //#pre[3] (String getPermalink(Month)): this.blog != null
    //#post(String getPermalink(Month)): init'ed(return_value)
      format.setTimeZone(blog.getTimeZone());
    //#latin1seopermalinkprovider.java:147: Warning: method not available
    //#    -- call on TimeZone net.sourceforge.pebble.domain.Blog:getTimeZone()
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: String getPermalink(Month)
    //#    unanalyzed callee: TimeZone net.sourceforge.pebble.domain.Blog:getTimeZone()
      return format.format(month.getDate());
    //#latin1seopermalinkprovider.java:148: Warning: method not available
    //#    -- call on Date net.sourceforge.pebble.domain.Month:getDate()
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: String getPermalink(Month)
    //#    unanalyzed callee: Date net.sourceforge.pebble.domain.Month:getDate()
    //#latin1seopermalinkprovider.java:148: end of method: String net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.getPermalink(Month)
    }

    /**
     * Determines whether the specified URI is a monthly blog permalink.
     *
     * @param uri   a relative URI
     * @return      true if the URI represents a permalink to a monthly blog,
     *              false otherwise
     */
    public boolean isMonthPermalink(String uri) {
      if (uri != null) {
    //#latin1seopermalinkprovider.java:159: method: bool net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.isMonthPermalink(String)
    //#input(bool isMonthPermalink(String)): uri
    //#output(bool isMonthPermalink(String)): return_value
    //#post(bool isMonthPermalink(String)): init'ed(return_value)
    //#test_vector(bool isMonthPermalink(String)): uri: Addr_Set{null}, Inverse{null}
        return uri.matches(MONTH_PERMALINK_REGEX);
      } else {
        return false;
    //#latin1seopermalinkprovider.java:162: end of method: bool net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.isMonthPermalink(String)
      }
    }

    /**
     * Gets the monthly blog referred to by the specified URI.
     *
     * @param uri   a relative URI
     * @return  a Month instance, or null if one can't be found
     */
    public Month getMonth(String uri) {
      String year = uri.substring(1, 5);
    //#latin1seopermalinkprovider.java:173: method: Month net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.getMonth(String)
    //#input(Month getMonth(String)): __Descendant_Table[net/sourceforge/pebble/permalink/Latin1SeoPermalinkProvider]
    //#input(Month getMonth(String)): __Descendant_Table[others]
    //#input(Month getMonth(String)): __Dispatch_Table.getBlog()Lnet/sourceforge/pebble/domain/Blog;
    //#input(Month getMonth(String)): this
    //#input(Month getMonth(String)): this.__Tag
    //#input(Month getMonth(String)): this.blog
    //#input(Month getMonth(String)): uri
    //#output(Month getMonth(String)): return_value
    //#pre[2] (Month getMonth(String)): this.__Tag == net/sourceforge/pebble/permalink/Latin1SeoPermalinkProvider
    //#pre[3] (Month getMonth(String)): this.blog != null
    //#pre[4] (Month getMonth(String)): uri != null
    //#post(Month getMonth(String)): init'ed(return_value)
      String month = uri.substring(6, 8);

      return getBlog().getBlogForMonth(Integer.parseInt(year), Integer.parseInt(month));
    //#latin1seopermalinkprovider.java:176: Warning: method not available
    //#    -- call on Month net.sourceforge.pebble.domain.Blog:getBlogForMonth(int, int)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: Month getMonth(String)
    //#    unanalyzed callee: Month net.sourceforge.pebble.domain.Blog:getBlogForMonth(int, int)
    //#latin1seopermalinkprovider.java:176: end of method: Month net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.getMonth(String)
    }

    /**
     * Gets the permalink for a day.
     *
     * @param day a Day instance
     * @return a URI as a String
     */
    public String getPermalink(Day day) {
      SimpleDateFormat format = new SimpleDateFormat("'/'yyyy'/'MM'/'dd");
    //#latin1seopermalinkprovider.java:186: method: String net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.getPermalink(Day)
    //#input(String getPermalink(Day)): day
    //#input(String getPermalink(Day)): this
    //#input(String getPermalink(Day)): this.blog
    //#output(String getPermalink(Day)): return_value
    //#pre[1] (String getPermalink(Day)): day != null
    //#pre[3] (String getPermalink(Day)): this.blog != null
    //#post(String getPermalink(Day)): init'ed(return_value)
      format.setTimeZone(blog.getTimeZone());
    //#latin1seopermalinkprovider.java:187: Warning: method not available
    //#    -- call on TimeZone net.sourceforge.pebble.domain.Blog:getTimeZone()
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: String getPermalink(Day)
    //#    unanalyzed callee: TimeZone net.sourceforge.pebble.domain.Blog:getTimeZone()
      return format.format(day.getDate());
    //#latin1seopermalinkprovider.java:188: Warning: method not available
    //#    -- call on Date net.sourceforge.pebble.domain.Day:getDate()
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: String getPermalink(Day)
    //#    unanalyzed callee: Date net.sourceforge.pebble.domain.Day:getDate()
    //#latin1seopermalinkprovider.java:188: end of method: String net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.getPermalink(Day)
    }

    /**
     * Determines whether the specified URI is a day permalink.
     *
     * @param uri   a relative URI
     * @return      true if the URI represents a permalink to a day,
     *              false otherwise
     */
    public boolean isDayPermalink(String uri) {
      if (uri != null) {
    //#latin1seopermalinkprovider.java:199: method: bool net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.isDayPermalink(String)
    //#input(bool isDayPermalink(String)): uri
    //#output(bool isDayPermalink(String)): return_value
    //#post(bool isDayPermalink(String)): init'ed(return_value)
    //#test_vector(bool isDayPermalink(String)): uri: Addr_Set{null}, Inverse{null}
        return uri.matches(DAY_PERMALINK_REGEX);
      } else {
        return false;
    //#latin1seopermalinkprovider.java:202: end of method: bool net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.isDayPermalink(String)
      }
    }

    /**
     * Gets the day referred to by the specified URI.
     *
     * @param uri   a relative URI
     * @return  a Day instance, or null if one can't be found
     */
    public Day getDay(String uri) {
      String year = uri.substring(1, 5);
    //#latin1seopermalinkprovider.java:213: method: Day net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.getDay(String)
    //#input(Day getDay(String)): __Descendant_Table[net/sourceforge/pebble/permalink/Latin1SeoPermalinkProvider]
    //#input(Day getDay(String)): __Descendant_Table[others]
    //#input(Day getDay(String)): __Dispatch_Table.getBlog()Lnet/sourceforge/pebble/domain/Blog;
    //#input(Day getDay(String)): this
    //#input(Day getDay(String)): this.__Tag
    //#input(Day getDay(String)): this.blog
    //#input(Day getDay(String)): uri
    //#output(Day getDay(String)): return_value
    //#pre[2] (Day getDay(String)): this.__Tag == net/sourceforge/pebble/permalink/Latin1SeoPermalinkProvider
    //#pre[3] (Day getDay(String)): this.blog != null
    //#pre[4] (Day getDay(String)): uri != null
    //#post(Day getDay(String)): init'ed(return_value)
      String month = uri.substring(6, 8);
      String day = uri.substring(9, 11);

      return getBlog().getBlogForDay(Integer.parseInt(year),
    //#latin1seopermalinkprovider.java:217: Warning: method not available
    //#    -- call on Day net.sourceforge.pebble.domain.Blog:getBlogForDay(int, int, int)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
    //#    method: Day getDay(String)
    //#    unanalyzed callee: Day net.sourceforge.pebble.domain.Blog:getBlogForDay(int, int, int)
         Integer.parseInt(month), Integer.parseInt(day));
    //#latin1seopermalinkprovider.java:218: end of method: Day net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.getDay(String)
    }


    /** the List of characters that will be substituted */
    private static final HashMap<String,String> characterSubstitutions;
    static {

        characterSubstitutions = new HashMap<String,String>();
    //#latin1seopermalinkprovider.java:226: method: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init
    //#output(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Descendant_Table[net/sourceforge/pebble/permalink/Latin1SeoPermalinkProvider]
    //#output(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.buildPermalink(Lnet/sourceforge/pebble/domain/BlogEntry;)Ljava/lang/String;
    //#output(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.getBlog()Lnet/sourceforge/pebble/domain/Blog;
    //#output(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.getBlogEntry(Ljava/lang/String;)Lnet/sourceforge/pebble/domain/BlogEntry;
    //#output(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.getDay(Ljava/lang/String;)Lnet/sourceforge/pebble/domain/Day;
    //#output(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.getMonth(Ljava/lang/String;)Lnet/sourceforge/pebble/domain/Month;
    //#output(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.getPermalink(Lnet/sourceforge/pebble/domain/BlogEntry;)Ljava/lang/String;
    //#output(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.getPermalink(Lnet/sourceforge/pebble/domain/Day;)Ljava/lang/String;
    //#output(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.getPermalink(Lnet/sourceforge/pebble/domain/Month;)Ljava/lang/String;
    //#output(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.isBlogEntryPermalink(Ljava/lang/String;)Z
    //#output(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.isDayPermalink(Ljava/lang/String;)Z
    //#output(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.isMonthPermalink(Ljava/lang/String;)Z
    //#output(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.setBlog(Lnet/sourceforge/pebble/domain/Blog;)V
    //#output(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): characterSubstitutions
    //#output(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): new HashMap(Latin1SeoPermalinkProvider__static_init#1) num objects
    //#new obj(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): new HashMap(Latin1SeoPermalinkProvider__static_init#1)
    //#post(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Descendant_Table[net/sourceforge/pebble/permalink/Latin1SeoPermalinkProvider] == &__Dispatch_Table
    //#post(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.buildPermalink(Lnet/sourceforge/pebble/domain/BlogEntry;)Ljava/lang/String; == &buildPermalink
    //#post(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.getBlog()Lnet/sourceforge/pebble/domain/Blog; == &getBlog
    //#post(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.getBlogEntry(Ljava/lang/String;)Lnet/sourceforge/pebble/domain/BlogEntry; == &getBlogEntry
    //#post(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.getDay(Ljava/lang/String;)Lnet/sourceforge/pebble/domain/Day; == &getDay
    //#post(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.getMonth(Ljava/lang/String;)Lnet/sourceforge/pebble/domain/Month; == &getMonth
    //#post(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.getPermalink(Lnet/sourceforge/pebble/domain/BlogEntry;)Ljava/lang/String; == &getPermalink
    //#post(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.getPermalink(Lnet/sourceforge/pebble/domain/Day;)Ljava/lang/String; == &getPermalink
    //#post(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.getPermalink(Lnet/sourceforge/pebble/domain/Month;)Ljava/lang/String; == &getPermalink
    //#post(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.isBlogEntryPermalink(Ljava/lang/String;)Z == &isBlogEntryPermalink
    //#post(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.isDayPermalink(Ljava/lang/String;)Z == &isDayPermalink
    //#post(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.isMonthPermalink(Ljava/lang/String;)Z == &isMonthPermalink
    //#post(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): __Dispatch_Table.setBlog(Lnet/sourceforge/pebble/domain/Blog;)V == &setBlog
    //#post(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): characterSubstitutions == &new HashMap(Latin1SeoPermalinkProvider__static_init#1)
    //#post(net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init): new HashMap(Latin1SeoPermalinkProvider__static_init#1) num objects == 1

        characterSubstitutions.put("\u00B2", "2");
        characterSubstitutions.put("\u00B3", "3");

        characterSubstitutions.put("\u00C0", "A");
        characterSubstitutions.put("\u00C1", "A");
        characterSubstitutions.put("\u00C2", "A");
        characterSubstitutions.put("\u00C3", "A");
        characterSubstitutions.put("\u00C4", "A");
        characterSubstitutions.put("\u00C5", "A");
        characterSubstitutions.put("\u00C6", "AE");
        characterSubstitutions.put("\u00C7", "C");
        characterSubstitutions.put("\u00C8", "E");
        characterSubstitutions.put("\u00C9", "E");
        characterSubstitutions.put("\u00CA", "E");
        characterSubstitutions.put("\u00CB", "E");
        characterSubstitutions.put("\u00CC", "I");
        characterSubstitutions.put("\u00CD", "I");
        characterSubstitutions.put("\u00CE", "I");
        characterSubstitutions.put("\u00CF", "I");

        characterSubstitutions.put("\u00D0", "D");
        characterSubstitutions.put("\u00D1", "N");
        characterSubstitutions.put("\u00D2", "O");
        characterSubstitutions.put("\u00D3", "O");
        characterSubstitutions.put("\u00D4", "O");
        characterSubstitutions.put("\u00D5", "O");
        characterSubstitutions.put("\u00D6", "O");
        characterSubstitutions.put("\u00D7", "x");
        characterSubstitutions.put("\u00D8", "O");
        characterSubstitutions.put("\u00D9", "U");
        characterSubstitutions.put("\u00DA", "U");
        characterSubstitutions.put("\u00DB", "U");
        characterSubstitutions.put("\u00DC", "U");
        characterSubstitutions.put("\u00DD", "Y");
        characterSubstitutions.put("\u00DE", "P");
        characterSubstitutions.put("\u00DF", "ss");

        characterSubstitutions.put("\u00E0", "a");
        characterSubstitutions.put("\u00E1", "a");
        characterSubstitutions.put("\u00E2", "a");
        characterSubstitutions.put("\u00E3", "a");
        characterSubstitutions.put("\u00E4", "a");
        characterSubstitutions.put("\u00E5", "a");
        characterSubstitutions.put("\u00E6", "ae");
        characterSubstitutions.put("\u00E7", "c");
        characterSubstitutions.put("\u00E8", "e");
        characterSubstitutions.put("\u00E9", "e");
        characterSubstitutions.put("\u00EA", "e");
        characterSubstitutions.put("\u00EB", "e");
        characterSubstitutions.put("\u00EC", "i");
        characterSubstitutions.put("\u00ED", "i");
        characterSubstitutions.put("\u00EE", "i");
        characterSubstitutions.put("\u00EF", "i");

        characterSubstitutions.put("\u00F0", "d");
        characterSubstitutions.put("\u00F1", "n");
        characterSubstitutions.put("\u00F2", "o");
        characterSubstitutions.put("\u00F3", "o");
        characterSubstitutions.put("\u00F4", "o");
        characterSubstitutions.put("\u00F5", "o");
        characterSubstitutions.put("\u00F6", "o");
        //"\u00F7", // division sign (ignore)
        characterSubstitutions.put("\u00F8", "o");
        characterSubstitutions.put("\u00F9", "u");
        characterSubstitutions.put("\u00FA", "u");
        characterSubstitutions.put("\u00FB", "u");
        characterSubstitutions.put("\u00FC", "u");
        characterSubstitutions.put("\u00FD", "y");
        characterSubstitutions.put("\u00FE", "p");
        characterSubstitutions.put("\u00FF", "y");
    //#latin1seopermalinkprovider.java:297: end of method: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider.net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider__static_init
    }
}
    //#latin1seopermalinkprovider.java:: end of class: net.sourceforge.pebble.permalink.Latin1SeoPermalinkProvider
