//# 1 errors, 508 messages
//#
/*
    //#category.java:1:1: class: net.sourceforge.pebble.domain.Category
 * Copyright (c) 2003-2006, Simon Brown
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *
 *   - Neither the name of Pebble nor the names of its contributors may
 *     be used to endorse or promote products derived from this software
 *     without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
package net.sourceforge.pebble.domain;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.Serializable;
import java.util.*;

import net.sourceforge.pebble.comparator.ReverseBlogEntryIdComparator;

/**
 * Represents a blog category.
 *
 * @author    Simon Brown
 */
public class Category implements Permalinkable, Comparable, Serializable {

  /** the log used by this class */
  private static final Log log = LogFactory.getLog(Category.class);
    //#category.java:50: method: net.sourceforge.pebble.domain.Category.net.sourceforge.pebble.domain.Category__static_init
    //#category.java:50: Warning: method not available
    //#    -- call on Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.domain.Category
    //#    method: net.sourceforge.pebble.domain.Category__static_init
    //#    unanalyzed callee: Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Descendant_Table[net/sourceforge/pebble/domain/Category]
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.addBlogEntry(Ljava/lang/String;)V
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.addSubCategory(Lnet/sourceforge/pebble/domain/Category;)V
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.compareTo(Ljava/lang/Object;)I
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.equals(Ljava/lang/Object;)Z
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getAllTags()Ljava/util/List;
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getBlogEntries()Ljava/util/List;
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getId()Ljava/lang/String;
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getName()Ljava/lang/String;
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getNumberOfBlogEntries()I
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getNumberOfParents()I
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getParent()Lnet/sourceforge/pebble/domain/Category;
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getPermalink()Ljava/lang/String;
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getSubCategories()Ljava/util/List;
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getTags()Ljava/lang/String;
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getTagsAsList()Ljava/util/List;
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.hasParent(Lnet/sourceforge/pebble/domain/Category;)Z
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.hashCode()I
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.isRootCategory()Z
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.removeAllBlogEntries()V
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.removeBlogEntry(Ljava/lang/String;)V
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.removeSubCategory(Lnet/sourceforge/pebble/domain/Category;)V
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.setBlog(Lnet/sourceforge/pebble/domain/Blog;)V
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.setId(Ljava/lang/String;)V
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.setName(Ljava/lang/String;)V
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.setParent(Lnet/sourceforge/pebble/domain/Category;)V
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.setTags(Ljava/lang/String;)V
    //#output(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.toString()Ljava/lang/String;
    //#output(net.sourceforge.pebble.domain.Category__static_init): log
    //#output(net.sourceforge.pebble.domain.Category__static_init): net/sourceforge/pebble/domain/Permalinkable.__Descendant_Table[net/sourceforge/pebble/domain/Category]
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Descendant_Table[net/sourceforge/pebble/domain/Category] == &__Dispatch_Table
    //#post(net.sourceforge.pebble.domain.Category__static_init): net/sourceforge/pebble/domain/Permalinkable.__Descendant_Table[net/sourceforge/pebble/domain/Category] == &__Dispatch_Table
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.addBlogEntry(Ljava/lang/String;)V == &addBlogEntry
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.addSubCategory(Lnet/sourceforge/pebble/domain/Category;)V == &addSubCategory
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.compareTo(Ljava/lang/Object;)I == &compareTo
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.equals(Ljava/lang/Object;)Z == &equals
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getAllTags()Ljava/util/List; == &getAllTags
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getBlogEntries()Ljava/util/List; == &getBlogEntries
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getId()Ljava/lang/String; == &getId
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getName()Ljava/lang/String; == &getName
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getNumberOfBlogEntries()I == &getNumberOfBlogEntries
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getNumberOfParents()I == &getNumberOfParents
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getParent()Lnet/sourceforge/pebble/domain/Category; == &getParent
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getPermalink()Ljava/lang/String; == &getPermalink
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getSubCategories()Ljava/util/List; == &getSubCategories
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getTags()Ljava/lang/String; == &getTags
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.getTagsAsList()Ljava/util/List; == &getTagsAsList
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.hasParent(Lnet/sourceforge/pebble/domain/Category;)Z == &hasParent
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.hashCode()I == &hashCode
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.isRootCategory()Z == &isRootCategory
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.removeAllBlogEntries()V == &removeAllBlogEntries
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.removeBlogEntry(Ljava/lang/String;)V == &removeBlogEntry
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.removeSubCategory(Lnet/sourceforge/pebble/domain/Category;)V == &removeSubCategory
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.setBlog(Lnet/sourceforge/pebble/domain/Blog;)V == &setBlog
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.setId(Ljava/lang/String;)V == &setId
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.setName(Ljava/lang/String;)V == &setName
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.setParent(Lnet/sourceforge/pebble/domain/Category;)V == &setParent
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.setTags(Ljava/lang/String;)V == &setTags
    //#post(net.sourceforge.pebble.domain.Category__static_init): __Dispatch_Table.toString()Ljava/lang/String; == &toString
    //#post(net.sourceforge.pebble.domain.Category__static_init): init'ed(log)
    //#category.java:50: end of method: net.sourceforge.pebble.domain.Category.net.sourceforge.pebble.domain.Category__static_init

  /** the root category identifier */
  private static final String ROOT_CATEGORY_IDENTIFIER = "/";

  /** the owning blog */
  private transient Blog blog;

  /** the id of the category */
  private String id = "";

  /** the name of the category */
  private String name = "";

  /** the parent category, if applicable */
  private Category parent = null;

  /** the set of tags for this category */
  private String tags = "";

  /** the list of tags for this category */
  private List tagsAsList = new ArrayList();

  /** the sub-categories */
  private List subCategories = new ArrayList();

  /** the blog entries associated with this category */
  private List<String> blogEntries = new ArrayList<String>();

  /**
   * Default, no args constructor.
   */
  public Category() {
    //#category.java:82: method: void net.sourceforge.pebble.domain.Category.net.sourceforge.pebble.domain.Category()
    //#input(void net.sourceforge.pebble.domain.Category()): this
    //#output(void net.sourceforge.pebble.domain.Category()): new ArrayList(Category#1) num objects
    //#output(void net.sourceforge.pebble.domain.Category()): new ArrayList(Category#2) num objects
    //#output(void net.sourceforge.pebble.domain.Category()): new ArrayList(Category#3) num objects
    //#output(void net.sourceforge.pebble.domain.Category()): this.blogEntries
    //#output(void net.sourceforge.pebble.domain.Category()): this.id
    //#output(void net.sourceforge.pebble.domain.Category()): this.name
    //#output(void net.sourceforge.pebble.domain.Category()): this.parent
    //#output(void net.sourceforge.pebble.domain.Category()): this.subCategories
    //#output(void net.sourceforge.pebble.domain.Category()): this.tags
    //#output(void net.sourceforge.pebble.domain.Category()): this.tagsAsList
    //#new obj(void net.sourceforge.pebble.domain.Category()): new ArrayList(Category#1)
    //#new obj(void net.sourceforge.pebble.domain.Category()): new ArrayList(Category#2)
    //#new obj(void net.sourceforge.pebble.domain.Category()): new ArrayList(Category#3)
    //#post(void net.sourceforge.pebble.domain.Category()): this.blogEntries == &new ArrayList(Category#3)
    //#post(void net.sourceforge.pebble.domain.Category()): this.id == &""
    //#post(void net.sourceforge.pebble.domain.Category()): this.name == &""
    //#post(void net.sourceforge.pebble.domain.Category()): this.tags == &""
    //#post(void net.sourceforge.pebble.domain.Category()): this.parent == null
    //#post(void net.sourceforge.pebble.domain.Category()): this.subCategories == &new ArrayList(Category#2)
    //#post(void net.sourceforge.pebble.domain.Category()): this.tagsAsList == &new ArrayList(Category#1)
    //#post(void net.sourceforge.pebble.domain.Category()): new ArrayList(Category#1) num objects == 1
    //#post(void net.sourceforge.pebble.domain.Category()): new ArrayList(Category#2) num objects == 1
    //#post(void net.sourceforge.pebble.domain.Category()): new ArrayList(Category#3) num objects == 1
  }
    //#category.java:83: end of method: void net.sourceforge.pebble.domain.Category.net.sourceforge.pebble.domain.Category()

  /**
   * Creates a new category with the specified properties.
   *
   * @param id          the id
   * @param name          the name
   */
  public Category(String id, String name) {
    //#category.java:91: method: void net.sourceforge.pebble.domain.Category.net.sourceforge.pebble.domain.Category(String, String)
    //#input(void net.sourceforge.pebble.domain.Category(String, String)): __Descendant_Table[net/sourceforge/pebble/domain/Category]
    //#input(void net.sourceforge.pebble.domain.Category(String, String)): __Descendant_Table[others]
    //#input(void net.sourceforge.pebble.domain.Category(String, String)): __Dispatch_Table.setId(Ljava/lang/String;)V
    //#input(void net.sourceforge.pebble.domain.Category(String, String)): id
    //#input(void net.sourceforge.pebble.domain.Category(String, String)): name
    //#input(void net.sourceforge.pebble.domain.Category(String, String)): this
    //#input(void net.sourceforge.pebble.domain.Category(String, String)): this.__Tag
    //#output(void net.sourceforge.pebble.domain.Category(String, String)): new ArrayList(Category#1) num objects
    //#output(void net.sourceforge.pebble.domain.Category(String, String)): new ArrayList(Category#2) num objects
    //#output(void net.sourceforge.pebble.domain.Category(String, String)): new ArrayList(Category#3) num objects
    //#output(void net.sourceforge.pebble.domain.Category(String, String)): this.blogEntries
    //#output(void net.sourceforge.pebble.domain.Category(String, String)): this.id
    //#output(void net.sourceforge.pebble.domain.Category(String, String)): this.name
    //#output(void net.sourceforge.pebble.domain.Category(String, String)): this.parent
    //#output(void net.sourceforge.pebble.domain.Category(String, String)): this.subCategories
    //#output(void net.sourceforge.pebble.domain.Category(String, String)): this.tags
    //#output(void net.sourceforge.pebble.domain.Category(String, String)): this.tagsAsList
    //#new obj(void net.sourceforge.pebble.domain.Category(String, String)): new ArrayList(Category#1)
    //#new obj(void net.sourceforge.pebble.domain.Category(String, String)): new ArrayList(Category#2)
    //#new obj(void net.sourceforge.pebble.domain.Category(String, String)): new ArrayList(Category#3)
    //#pre[4] (void net.sourceforge.pebble.domain.Category(String, String)): this.__Tag == net/sourceforge/pebble/domain/Category
    //#post(void net.sourceforge.pebble.domain.Category(String, String)): this.blogEntries == &new ArrayList(Category#3)
    //#post(void net.sourceforge.pebble.domain.Category(String, String)): this.id != null
    //#post(void net.sourceforge.pebble.domain.Category(String, String)): this.name == name
    //#post(void net.sourceforge.pebble.domain.Category(String, String)): init'ed(this.name)
    //#post(void net.sourceforge.pebble.domain.Category(String, String)): init'ed(this.parent)
    //#post(void net.sourceforge.pebble.domain.Category(String, String)): this.subCategories == &new ArrayList(Category#2)
    //#post(void net.sourceforge.pebble.domain.Category(String, String)): this.tags == &""
    //#post(void net.sourceforge.pebble.domain.Category(String, String)): this.tagsAsList == &new ArrayList(Category#1)
    //#post(void net.sourceforge.pebble.domain.Category(String, String)): new ArrayList(Category#1) num objects == 1
    //#post(void net.sourceforge.pebble.domain.Category(String, String)): new ArrayList(Category#2) num objects == 1
    //#post(void net.sourceforge.pebble.domain.Category(String, String)): new ArrayList(Category#3) num objects == 1
    //#unanalyzed(void net.sourceforge.pebble.domain.Category(String, String)): Effects-of-calling:java.lang.String:startsWith
    //#unanalyzed(void net.sourceforge.pebble.domain.Category(String, String)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void net.sourceforge.pebble.domain.Category(String, String)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void net.sourceforge.pebble.domain.Category(String, String)): Effects-of-calling:java.lang.StringBuilder:toString
    setId(id);

    this.name = name;
  }
    //#category.java:95: end of method: void net.sourceforge.pebble.domain.Category.net.sourceforge.pebble.domain.Category(String, String)

  /**
   * Gets the id of this category.
   *
   * @return    the id as a String
   */
  public String getId() {
    return id;
    //#category.java:103: method: String net.sourceforge.pebble.domain.Category.getId()
    //#input(String getId()): this
    //#input(String getId()): this.id
    //#output(String getId()): return_value
    //#pre[2] (String getId()): init'ed(this.id)
    //#post(String getId()): return_value == this.id
    //#post(String getId()): init'ed(return_value)
    //#category.java:103: end of method: String net.sourceforge.pebble.domain.Category.getId()
  }

  /**
   * Sets the id of this category.
   *
   * @param id    the id as a String
   */
  public void setId(String id) {
    this.id = id;
    //#category.java:112: method: void net.sourceforge.pebble.domain.Category.setId(String)
    //#input(void setId(String)): id
    //#input(void setId(String)): this
    //#output(void setId(String)): this.id
    //#post(void setId(String)): this.id != null
    //#test_vector(void setId(String)): id: Addr_Set{null}, Inverse{null}
    //#test_vector(void setId(String)): java.lang.String:startsWith(...)@113: {1}, {0}
    if (this.id == null || !this.id.startsWith("/")) {
      this.id = "/" + this.id;
    }
  }
    //#category.java:116: end of method: void net.sourceforge.pebble.domain.Category.setId(String)

  /**
   * Gets the name of this category.
   *
   * @return    the name as a String
   */
  public String getName() {
    return name;
    //#category.java:124: method: String net.sourceforge.pebble.domain.Category.getName()
    //#input(String getName()): this
    //#input(String getName()): this.name
    //#output(String getName()): return_value
    //#pre[2] (String getName()): init'ed(this.name)
    //#post(String getName()): return_value == this.name
    //#post(String getName()): init'ed(return_value)
    //#category.java:124: end of method: String net.sourceforge.pebble.domain.Category.getName()
  }

  /**
   * Sets the name of this category.
   *
   * @param name    the new category name
   */
  public void setName(String name) {
    this.name = name;
    //#category.java:133: method: void net.sourceforge.pebble.domain.Category.setName(String)
    //#input(void setName(String)): name
    //#input(void setName(String)): this
    //#output(void setName(String)): this.name
    //#post(void setName(String)): this.name == name
    //#post(void setName(String)): init'ed(this.name)
  }
    //#category.java:134: end of method: void net.sourceforge.pebble.domain.Category.setName(String)

  /**
   * Determines whether this category is a root category.
   *
   * @return  true if the ID is "/", false otherwise
   */
  public boolean isRootCategory() {
    return id.equals(ROOT_CATEGORY_IDENTIFIER);
    //#category.java:142: method: bool net.sourceforge.pebble.domain.Category.isRootCategory()
    //#input(bool isRootCategory()): this
    //#input(bool isRootCategory()): this.id
    //#output(bool isRootCategory()): return_value
    //#pre[2] (bool isRootCategory()): this.id != null
    //#post(bool isRootCategory()): init'ed(return_value)
    //#category.java:142: end of method: bool net.sourceforge.pebble.domain.Category.isRootCategory()
  }

  /**
   * Gets the parent of thie category.
   *
   * @return  a Category instance, or null if this category has no parent
   */
  public Category getParent() {
    return this.parent;
    //#category.java:151: method: Category net.sourceforge.pebble.domain.Category.getParent()
    //#input(Category getParent()): this
    //#input(Category getParent()): this.parent
    //#output(Category getParent()): return_value
    //#pre[2] (Category getParent()): init'ed(this.parent)
    //#post(Category getParent()): return_value == this.parent
    //#post(Category getParent()): init'ed(return_value)
    //#category.java:151: end of method: Category net.sourceforge.pebble.domain.Category.getParent()
  }

  /**
   * Determines whether this category has the specified parent.
   *
   * @param category    a Category to test for
   * @return  true if this category has the specified category as one of its
   *          parents, false otherwise
   */
  public boolean hasParent(Category category) {
    Category parent = getParent();
    //#category.java:162: method: bool net.sourceforge.pebble.domain.Category.hasParent(Category)
    //#input(bool hasParent(Category)): __Descendant_Table[net/sourceforge/pebble/domain/Category]
    //#input(bool hasParent(Category)): __Descendant_Table[others]
    //#input(bool hasParent(Category)): __Dispatch_Table.equals(Ljava/lang/Object;)Z
    //#input(bool hasParent(Category)): __Dispatch_Table.getId()Ljava/lang/String;
    //#input(bool hasParent(Category)): __Dispatch_Table.getParent()Lnet/sourceforge/pebble/domain/Category;
    //#input(bool hasParent(Category)): category
    //#input(bool hasParent(Category)): category.__Tag
    //#input(bool hasParent(Category)): category.id
    //#input(bool hasParent(Category)): this
    //#input(bool hasParent(Category)): this...__Tag
    //#input(bool hasParent(Category)): this...id
    //#input(bool hasParent(Category)): this...parent
    //#input(bool hasParent(Category)): this.__Tag
    //#input(bool hasParent(Category)): this.parent
    //#output(bool hasParent(Category)): return_value
    //#pre[8] (bool hasParent(Category)): this.__Tag == net/sourceforge/pebble/domain/Category
    //#pre[9] (bool hasParent(Category)): init'ed(this.parent)
    //#pre[3] (bool hasParent(Category)): (soft) category.id != null
    //#pre[5] (bool hasParent(Category)): (soft) this...__Tag == net/sourceforge/pebble/domain/Category
    //#pre[6] (bool hasParent(Category)): (soft) init'ed(this...id)
    //#pre[7] (bool hasParent(Category)): (soft) init'ed(this...parent)
    //#post(bool hasParent(Category)): init'ed(return_value)
    //#unanalyzed(bool hasParent(Category)): Effects-of-calling:java.lang.String:equals
    while (parent != null) {
      if (parent.equals(category)) {
        return true;
      } else {
        parent = parent.getParent();
      }
    }

    return false;
    //#category.java:171: end of method: bool net.sourceforge.pebble.domain.Category.hasParent(Category)
  }

  /**
   * Sets the parent of this category.
   *
   * @param parent  a Category instance
   */
  public void setParent(Category parent) {
    this.parent = parent;
    //#category.java:180: method: void net.sourceforge.pebble.domain.Category.setParent(Category)
    //#input(void setParent(Category)): parent
    //#input(void setParent(Category)): this
    //#output(void setParent(Category)): this.parent
    //#post(void setParent(Category)): this.parent == parent
    //#post(void setParent(Category)): init'ed(this.parent)
  }
    //#category.java:181: end of method: void net.sourceforge.pebble.domain.Category.setParent(Category)

  /**
   * Gets the number of parents that this category has.
   *
   * @return  the number of parents this category has, or 0 if it is
   *          the root category
   */
  public int getNumberOfParents() {
    int parents = 0;
    //#category.java:190: method: int net.sourceforge.pebble.domain.Category.getNumberOfParents()
    //#input(int getNumberOfParents()): __Descendant_Table[net/sourceforge/pebble/domain/Category]
    //#input(int getNumberOfParents()): __Descendant_Table[others]
    //#input(int getNumberOfParents()): __Dispatch_Table.getParent()Lnet/sourceforge/pebble/domain/Category;
    //#input(int getNumberOfParents()): this
    //#input(int getNumberOfParents()): this...__Tag
    //#input(int getNumberOfParents()): this...parent
    //#input(int getNumberOfParents()): this.__Tag
    //#input(int getNumberOfParents()): this.parent
    //#output(int getNumberOfParents()): return_value
    //#pre[4] (int getNumberOfParents()): this.__Tag == net/sourceforge/pebble/domain/Category
    //#pre[5] (int getNumberOfParents()): init'ed(this.parent)
    //#pre[2] (int getNumberOfParents()): (soft) this...__Tag == net/sourceforge/pebble/domain/Category
    //#pre[3] (int getNumberOfParents()): (soft) init'ed(this...parent)
    //#post(int getNumberOfParents()): return_value >= 0
    Category parent = getParent();
    while (parent != null) {
      parents++;
    //#category.java:193: ?overflow
    //#    parents in -2_147_483_649..4_294_967_294
    //#    severity: LOW
    //#    class: net.sourceforge.pebble.domain.Category
    //#    method: int getNumberOfParents()
    //#    basic block: bb_2
    //#    assertion: parents in -2_147_483_649..4_294_967_294
    //#    VN: parents + 1
    //#    Expected: {-2_147_483_648..4_294_967_295, Invalid}
    //#    Bad: {4_294_967_296}
    //#    Attribs:  Int  Bad singleton  Bad > Exp
      parent = parent.getParent();
    }

    return parents;
    //#category.java:197: end of method: int net.sourceforge.pebble.domain.Category.getNumberOfParents()
  }

  /**
   * Adds a sub-category.
   *
   * @param category    a Category instance
   */
  public synchronized void addSubCategory(Category category) {
    if (subCategories != null && !subCategories.contains(category)) {
    //#category.java:206: method: void net.sourceforge.pebble.domain.Category.addSubCategory(Category)
    //#input(void addSubCategory(Category)): __Descendant_Table[net/sourceforge/pebble/domain/Category]
    //#input(void addSubCategory(Category)): __Descendant_Table[others]
    //#input(void addSubCategory(Category)): __Dispatch_Table.setParent(Lnet/sourceforge/pebble/domain/Category;)V
    //#input(void addSubCategory(Category)): category
    //#input(void addSubCategory(Category)): category.__Tag
    //#input(void addSubCategory(Category)): this
    //#input(void addSubCategory(Category)): this.subCategories
    //#output(void addSubCategory(Category)): category.parent
    //#pre[5] (void addSubCategory(Category)): init'ed(this.subCategories)
    //#pre[1] (void addSubCategory(Category)): (soft) category != null
    //#pre[2] (void addSubCategory(Category)): (soft) category.__Tag == net/sourceforge/pebble/domain/Category
    //#post(void addSubCategory(Category)): category.parent == One-of{old category.parent, this}
    //#test_vector(void addSubCategory(Category)): this.subCategories: Addr_Set{null}, Inverse{null}
    //#test_vector(void addSubCategory(Category)): java.util.List:contains(...)@206: {1}, {0}
      subCategories.add(category);
      category.setParent(this);
    }
  }
    //#category.java:210: end of method: void net.sourceforge.pebble.domain.Category.addSubCategory(Category)

  /**
   * Removes a sub-category.
   *
   * @param category    a Category instance
   */
  public synchronized void removeSubCategory(Category category) {
    if (subCategories != null && subCategories.contains(category)) {
    //#category.java:218: method: void net.sourceforge.pebble.domain.Category.removeSubCategory(Category)
    //#input(void removeSubCategory(Category)): __Descendant_Table[net/sourceforge/pebble/domain/Category]
    //#input(void removeSubCategory(Category)): __Descendant_Table[others]
    //#input(void removeSubCategory(Category)): __Dispatch_Table.setParent(Lnet/sourceforge/pebble/domain/Category;)V
    //#input(void removeSubCategory(Category)): category
    //#input(void removeSubCategory(Category)): category.__Tag
    //#input(void removeSubCategory(Category)): this
    //#input(void removeSubCategory(Category)): this.subCategories
    //#output(void removeSubCategory(Category)): category.parent
    //#pre[5] (void removeSubCategory(Category)): init'ed(this.subCategories)
    //#pre[1] (void removeSubCategory(Category)): (soft) category != null
    //#pre[2] (void removeSubCategory(Category)): (soft) category.__Tag == net/sourceforge/pebble/domain/Category
    //#post(void removeSubCategory(Category)): category.parent == One-of{old category.parent, null}
    //#test_vector(void removeSubCategory(Category)): this.subCategories: Addr_Set{null}, Inverse{null}
    //#test_vector(void removeSubCategory(Category)): java.util.List:contains(...)@218: {0}, {1}
      subCategories.remove(category);
      category.setParent(null);
    }
  }
    //#category.java:222: end of method: void net.sourceforge.pebble.domain.Category.removeSubCategory(Category)

  /**
   * Gets the list of sub-categories.
   *
   * @return  a List of Category instances
   */
  public List getSubCategories() {
    return Collections.unmodifiableList(subCategories);
    //#category.java:230: method: List net.sourceforge.pebble.domain.Category.getSubCategories()
    //#input(List getSubCategories()): this
    //#input(List getSubCategories()): this.subCategories
    //#output(List getSubCategories()): return_value
    //#pre[2] (List getSubCategories()): init'ed(this.subCategories)
    //#post(List getSubCategories()): init'ed(return_value)
    //#category.java:230: end of method: List net.sourceforge.pebble.domain.Category.getSubCategories()
  }

  /**
   * Gets the tags associated with this category.
   *
   * @return  a list of tags
   */
  public String getTags() {
    return this.tags;
    //#category.java:239: method: String net.sourceforge.pebble.domain.Category.getTags()
    //#input(String getTags()): this
    //#input(String getTags()): this.tags
    //#output(String getTags()): return_value
    //#pre[2] (String getTags()): init'ed(this.tags)
    //#post(String getTags()): return_value == this.tags
    //#post(String getTags()): init'ed(return_value)
    //#category.java:239: end of method: String net.sourceforge.pebble.domain.Category.getTags()
  }

  /**
   * Gets the tags associated with this category, as a List.
   *
   * @return  a List of tags
   */
  public List getTagsAsList() {
    return this.tagsAsList;
    //#category.java:248: method: List net.sourceforge.pebble.domain.Category.getTagsAsList()
    //#input(List getTagsAsList()): this
    //#input(List getTagsAsList()): this.tagsAsList
    //#output(List getTagsAsList()): return_value
    //#pre[2] (List getTagsAsList()): init'ed(this.tagsAsList)
    //#post(List getTagsAsList()): return_value == this.tagsAsList
    //#post(List getTagsAsList()): init'ed(return_value)
    //#category.java:248: end of method: List net.sourceforge.pebble.domain.Category.getTagsAsList()
  }

  /**
   * Gets the tags associated with this category and its parents.
   *
   * @return  a list of tags
   */
  public List getAllTags() {
    List l = new ArrayList();
    //#category.java:257: method: List net.sourceforge.pebble.domain.Category.getAllTags()
    //#input(List getAllTags()): __Descendant_Table[net/sourceforge/pebble/domain/Category]
    //#input(List getAllTags()): __Descendant_Table[others]
    //#input(List getAllTags()): __Dispatch_Table.getParent()Lnet/sourceforge/pebble/domain/Category;
    //#input(List getAllTags()): __Dispatch_Table.getTagsAsList()Ljava/util/List;
    //#input(List getAllTags()): this
    //#input(List getAllTags()): this...__Tag
    //#input(List getAllTags()): this...parent
    //#input(List getAllTags()): this...tagsAsList
    //#input(List getAllTags()): this.__Tag
    //#input(List getAllTags()): this.parent
    //#input(List getAllTags()): this.tagsAsList
    //#output(List getAllTags()): new ArrayList(getAllTags#1) num objects
    //#output(List getAllTags()): return_value
    //#new obj(List getAllTags()): new ArrayList(getAllTags#1)
    //#pre[5] (List getAllTags()): this.__Tag == net/sourceforge/pebble/domain/Category
    //#pre[6] (List getAllTags()): init'ed(this.parent)
    //#pre[7] (List getAllTags()): init'ed(this.tagsAsList)
    //#pre[2] (List getAllTags()): (soft) this...__Tag == net/sourceforge/pebble/domain/Category
    //#pre[3] (List getAllTags()): (soft) init'ed(this...parent)
    //#pre[4] (List getAllTags()): (soft) init'ed(this...tagsAsList)
    //#post(List getAllTags()): return_value == &new ArrayList(getAllTags#1)
    //#post(List getAllTags()): new ArrayList(getAllTags#1) num objects == 1

    l.addAll(getTagsAsList());
    Category parent = getParent();
    while (parent != null) {
      l.addAll(parent.getTagsAsList());
      parent = parent.getParent();
    }

    return l;
    //#category.java:266: end of method: List net.sourceforge.pebble.domain.Category.getAllTags()
  }

  /**
   * Sets the set of tags associated with this category.
   *
   * @param newTags    a set of tags
   */
  public void setTags(String newTags) {
    if (newTags != null && newTags.indexOf(",") > -1) {
    //#category.java:275: method: void net.sourceforge.pebble.domain.Category.setTags(String)
    //#input(void setTags(String)): net/sourceforge/pebble/domain/Tag.__Descendant_Table[net/sourceforge/pebble/domain/Tag]
    //#input(void setTags(String)): net/sourceforge/pebble/domain/Tag.__Descendant_Table[net/sourceforge/pebble/index/IndexedTag]
    //#input(void setTags(String)): net/sourceforge/pebble/domain/Tag.__Descendant_Table[others]
    //#input(void setTags(String)): net/sourceforge/pebble/domain/Tag.__Dispatch_Table.setName(Ljava/lang/String;)V
    //#input(void setTags(String)): net/sourceforge/pebble/index/IndexedTag.__Dispatch_Table.setName(Ljava/lang/String;)V
    //#input(void setTags(String)): newTags
    //#input(void setTags(String)): this
    //#input(void setTags(String)): this.blog
    //#output(void setTags(String)): new ArrayList(parse#1) num objects
    //#output(void setTags(String)): this.tags
    //#output(void setTags(String)): this.tagsAsList
    //#new obj(void setTags(String)): new ArrayList(parse#1)
    //#pre[3] (void setTags(String)): init'ed(this.blog)
    //#post(void setTags(String)): init'ed(this.tags)
    //#post(void setTags(String)): this.tagsAsList == &new ArrayList(parse#1)
    //#post(void setTags(String)): new ArrayList(parse#1) num objects == 1
    //#unanalyzed(void setTags(String)): Effects-of-calling:java.lang.String:trim
    //#unanalyzed(void setTags(String)): Effects-of-calling:java.lang.String:toLowerCase
    //#unanalyzed(void setTags(String)): Effects-of-calling:java.lang.String:replaceAll
    //#unanalyzed(void setTags(String)): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(void setTags(String)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(void setTags(String)): Effects-of-calling:java.lang.String:split
    //#unanalyzed(void setTags(String)): Effects-of-calling:net.sourceforge.pebble.util.StringUtils:transformHTML
    //#unanalyzed(void setTags(String)): Effects-of-calling:java.util.List:contains
    //#unanalyzed(void setTags(String)): Effects-of-calling:java.util.List:add
    //#test_vector(void setTags(String)): newTags: Addr_Set{null}, Inverse{null}
    //#test_vector(void setTags(String)): java.lang.String:indexOf(...)@275: {-2_147_483_648..-1}, {0..4_294_967_295}
      // if the tags have been comma separated, convert them to
      // whitespace separated by
      // - remove whitespace
      // - convert commas to whitespace
      newTags = newTags.replaceAll(" ", "").replaceAll(",", " ");
    }
    this.tags = newTags;
    this.tagsAsList = Tag.parse(blog, tags);
  }
    //#category.java:284: end of method: void net.sourceforge.pebble.domain.Category.setTags(String)

  /**
   * Sets the owning blog.
   *
   * @param blog    a Blog instance
   */
  public void setBlog(Blog blog) {
    this.blog = blog;
    //#category.java:292: method: void net.sourceforge.pebble.domain.Category.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)
  }
    //#category.java:293: end of method: void net.sourceforge.pebble.domain.Category.setBlog(Blog)

  /**
   * Gets the permalink for this object.
   *
   * @return  a URL as a String
   */
  public String getPermalink() {
    if (isRootCategory()) {
    //#category.java:301: method: String net.sourceforge.pebble.domain.Category.getPermalink()
    //#input(String getPermalink()): __Descendant_Table[net/sourceforge/pebble/domain/Category]
    //#input(String getPermalink()): __Descendant_Table[others]
    //#input(String getPermalink()): __Dispatch_Table.isRootCategory()Z
    //#input(String getPermalink()): net/sourceforge/pebble/Configuration.__Descendant_Table[net/sourceforge/pebble/Configuration]
    //#input(String getPermalink()): net/sourceforge/pebble/Configuration.__Descendant_Table[others]
    //#input(String getPermalink()): net/sourceforge/pebble/Configuration.__Dispatch_Table.getUrl()Ljava/lang/String;
    //#input(String getPermalink()): net/sourceforge/pebble/Configuration.__Dispatch_Table.isVirtualHostingEnabled()Z
    //#input(String getPermalink()): net/sourceforge/pebble/domain/Blog.__Descendant_Table[net/sourceforge/pebble/domain/Blog]
    //#input(String getPermalink()): net/sourceforge/pebble/domain/Blog.__Descendant_Table[others]
    //#input(String getPermalink()): net/sourceforge/pebble/domain/Blog.__Dispatch_Table.getId()Ljava/lang/String;
    //#input(String getPermalink()): net/sourceforge/pebble/domain/Blog.__Dispatch_Table.getUrl()Ljava/lang/String;
    //#input(String getPermalink()): net/sourceforge/pebble/domain/BlogManager.__Descendant_Table[net/sourceforge/pebble/domain/BlogManager]
    //#input(String getPermalink()): net/sourceforge/pebble/domain/BlogManager.__Descendant_Table[others]
    //#input(String getPermalink()): net/sourceforge/pebble/domain/BlogManager.__Dispatch_Table.isMultiBlog()Z
    //#input(String getPermalink()): net/sourceforge/pebble/domain/BlogManager.instance
    //#input(String getPermalink()): net/sourceforge/pebble/domain/BlogManager.instance.__Tag
    //#input(String getPermalink()): net/sourceforge/pebble/domain/BlogManager.instance.multiBlog
    //#input(String getPermalink()): this
    //#input(String getPermalink()): this.__Tag
    //#input(String getPermalink()): this.blog
    //#input(String getPermalink()): this.blog.__Tag
    //#input(String getPermalink()): this.blog.id
    //#input(String getPermalink()): this.id
    //#output(String getPermalink()): return_value
    //#pre[5] (String getPermalink()): this.__Tag == net/sourceforge/pebble/domain/Category
    //#pre[6] (String getPermalink()): this.blog != null
    //#pre[7] (String getPermalink()): this.blog.__Tag == net/sourceforge/pebble/domain/Blog
    //#pre[9] (String getPermalink()): this.id != null
    //#pre[1] (String getPermalink()): (soft) net/sourceforge/pebble/domain/BlogManager.instance != null
    //#pre[2] (String getPermalink()): (soft) net/sourceforge/pebble/domain/BlogManager.instance.__Tag == net/sourceforge/pebble/domain/BlogManager
    //#pre[3] (String getPermalink()): (soft) init'ed(net/sourceforge/pebble/domain/BlogManager.instance.multiBlog)
    //#pre[8] (String getPermalink()): (soft) init'ed(this.blog.id)
    //#post(String getPermalink()): return_value != null
    //#unanalyzed(String getPermalink()): Effects-of-calling:java.lang.String:equals
    //#unanalyzed(String getPermalink()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(String getPermalink()): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(String getPermalink()): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(String getPermalink()): Effects-of-calling:java.lang.String:valueOf
    //#unanalyzed(String getPermalink()): Effects-of-calling:java.lang.String:indexOf
    //#unanalyzed(String getPermalink()): Effects-of-calling:net.sourceforge.pebble.PebbleContext:getInstance
    //#unanalyzed(String getPermalink()): Effects-of-calling:net.sourceforge.pebble.PebbleContext:getConfiguration
    //#unanalyzed(String getPermalink()): Effects-of-calling:java.lang.String:length
    //#unanalyzed(String getPermalink()): Effects-of-calling:java.lang.String:substring
    //#test_vector(String getPermalink()): java.lang.String:equals(...)@142: {0}, {1}
      return blog.getUrl() + "categories/";
    } else {
      return blog.getUrl() + "categories" + id + "/";
    //#category.java:304: end of method: String net.sourceforge.pebble.domain.Category.getPermalink()
    }
  }

  /**
   * Gets the hashcode of this object.
   *
   * @return  the hashcode as an int
   */
  public int hashCode() {
    return id.hashCode();
    //#category.java:314: method: int net.sourceforge.pebble.domain.Category.hashCode()
    //#input(int hashCode()): this
    //#input(int hashCode()): this.id
    //#output(int hashCode()): return_value
    //#pre[2] (int hashCode()): this.id != null
    //#post(int hashCode()): init'ed(return_value)
    //#category.java:314: end of method: int net.sourceforge.pebble.domain.Category.hashCode()
  }

  /**
   * Determines whether the specified object is equal to this one.
   *
   * @param o   the object to compare against
   * @return    true if Object o represents the same category, false otherwise
   */
  public boolean equals(Object o) {
    if (!(o instanceof Category)) {
    //#category.java:324: method: bool net.sourceforge.pebble.domain.Category.equals(Object)
    //#input(bool equals(Object)): __Descendant_Table[net/sourceforge/pebble/domain/Category]
    //#input(bool equals(Object)): __Descendant_Table[others]
    //#input(bool equals(Object)): __Dispatch_Table.getId()Ljava/lang/String;
    //#input(bool equals(Object)): o
    //#input(bool equals(Object)): o.__Tag
    //#input(bool equals(Object)): o.id
    //#input(bool equals(Object)): this
    //#input(bool equals(Object)): this.id
    //#output(bool equals(Object)): return_value
    //#pre[3] (bool equals(Object)): (soft) o.id != null
    //#pre[5] (bool equals(Object)): (soft) init'ed(this.id)
    //#post(bool equals(Object)): init'ed(return_value)
      return false;
    }

    Category cat = (Category)o;
    return (cat.getId().equals(id));
    //#category.java:329: end of method: bool net.sourceforge.pebble.domain.Category.equals(Object)
  }

  /**
   * Compares this object with the specified object for order.  Returns a
   * negative integer, zero, or a positive integer as this object is less
   * than, equal to, or greater than the specified object.<p>
   *
   * @param   o the Object to be compared.
   * @return  a negative integer, zero, or a positive integer as this object
   *		is less than, equal to, or greater than the specified object.
   *
   * @throws ClassCastException if the specified object's type prevents it
   *         from being compared to this Object.
   */
  public int compareTo(Object o) {
    Category category = (Category)o;
    //#category.java:345: method: int net.sourceforge.pebble.domain.Category.compareTo(Object)
    //#input(int compareTo(Object)): __Descendant_Table[net/sourceforge/pebble/domain/Category]
    //#input(int compareTo(Object)): __Descendant_Table[others]
    //#input(int compareTo(Object)): __Dispatch_Table.getId()Ljava/lang/String;
    //#input(int compareTo(Object)): o
    //#input(int compareTo(Object)): o.__Tag
    //#input(int compareTo(Object)): o.id
    //#input(int compareTo(Object)): this
    //#input(int compareTo(Object)): this.__Tag
    //#input(int compareTo(Object)): this.id
    //#output(int compareTo(Object)): return_value
    //#pre[1] (int compareTo(Object)): o != null
    //#pre[2] (int compareTo(Object)): o.__Tag == net/sourceforge/pebble/domain/Category
    //#pre[3] (int compareTo(Object)): init'ed(o.id)
    //#pre[5] (int compareTo(Object)): this.__Tag == net/sourceforge/pebble/domain/Category
    //#pre[6] (int compareTo(Object)): this.id != null
    //#post(int compareTo(Object)): init'ed(return_value)
    return getId().compareTo(category.getId());
    //#category.java:346: end of method: int net.sourceforge.pebble.domain.Category.compareTo(Object)
  }

  /**
   * Returns a String representation of this object.
   *
   * @return  a String
   */
  public String toString() {
    return this.name;
    //#category.java:355: method: String net.sourceforge.pebble.domain.Category.toString()
    //#input(String toString()): this
    //#input(String toString()): this.name
    //#output(String toString()): return_value
    //#pre[2] (String toString()): init'ed(this.name)
    //#post(String toString()): return_value == this.name
    //#post(String toString()): init'ed(return_value)
    //#category.java:355: end of method: String net.sourceforge.pebble.domain.Category.toString()
  }

  /**
   * Gets the blog entries associated with this category.
   *
   * @return  a Collection of BlogEntry instances
   */
  public List<String> getBlogEntries() {
    return new ArrayList<String>(blogEntries);
    //#category.java:364: method: List net.sourceforge.pebble.domain.Category.getBlogEntries()
    //#input(List getBlogEntries()): this
    //#input(List getBlogEntries()): this.blogEntries
    //#output(List getBlogEntries()): new ArrayList(getBlogEntries#1) num objects
    //#output(List getBlogEntries()): return_value
    //#new obj(List getBlogEntries()): new ArrayList(getBlogEntries#1)
    //#pre[2] (List getBlogEntries()): init'ed(this.blogEntries)
    //#post(List getBlogEntries()): return_value == &new ArrayList(getBlogEntries#1)
    //#post(List getBlogEntries()): new ArrayList(getBlogEntries#1) num objects == 1
    //#category.java:364: end of method: List net.sourceforge.pebble.domain.Category.getBlogEntries()
  }

  /**
   * Adds a blog entry to this category.
   *
   * @param blogEntry   a blog entry id
   */
  public synchronized void addBlogEntry(String blogEntry) {
    if (blogEntry != null && !blogEntries.contains(blogEntry)) {
    //#category.java:373: method: void net.sourceforge.pebble.domain.Category.addBlogEntry(String)
    //#input(void addBlogEntry(String)): __Descendant_Table[net/sourceforge/pebble/domain/Category]
    //#input(void addBlogEntry(String)): __Descendant_Table[others]
    //#input(void addBlogEntry(String)): __Dispatch_Table.addBlogEntry(Ljava/lang/String;)V
    //#input(void addBlogEntry(String)): __Dispatch_Table.getParent()Lnet/sourceforge/pebble/domain/Category;
    //#input(void addBlogEntry(String)): blogEntry
    //#input(void addBlogEntry(String)): this
    //#input(void addBlogEntry(String)): this...__Tag
    //#input(void addBlogEntry(String)): this...blogEntries
    //#input(void addBlogEntry(String)): this...parent
    //#input(void addBlogEntry(String)): this.__Tag
    //#input(void addBlogEntry(String)): this.blogEntries
    //#input(void addBlogEntry(String)): this.parent
    //#pre[3] (void addBlogEntry(String)): (soft) this...__Tag == net/sourceforge/pebble/domain/Category
    //#pre[4] (void addBlogEntry(String)): (soft) this...blogEntries != null
    //#pre[5] (void addBlogEntry(String)): (soft) init'ed(this...parent)
    //#pre[6] (void addBlogEntry(String)): (soft) this.__Tag == net/sourceforge/pebble/domain/Category
    //#pre[7] (void addBlogEntry(String)): (soft) this.blogEntries != null
    //#pre[8] (void addBlogEntry(String)): (soft) init'ed(this.parent)
    //#unanalyzed(void addBlogEntry(String)): Effects-of-calling:java.util.List:contains
    //#unanalyzed(void addBlogEntry(String)): Effects-of-calling:java.util.List:add
    //#unanalyzed(void addBlogEntry(String)): Effects-of-calling:java.util.Collections:sort
    //#unanalyzed(void addBlogEntry(String)): Effects-of-calling:addBlogEntry
    //#test_vector(void addBlogEntry(String)): blogEntry: Addr_Set{null}, Inverse{null}
    //#test_vector(void addBlogEntry(String)): this.parent: Addr_Set{null}, Inverse{null}
    //#test_vector(void addBlogEntry(String)): java.util.List:contains(...)@373: {1}, {0}
      blogEntries.add(blogEntry);
      Collections.sort(blogEntries, new ReverseBlogEntryIdComparator());

      if (getParent() != null) {
        getParent().addBlogEntry(blogEntry);
      }
    }
  }
    //#category.java:381: end of method: void net.sourceforge.pebble.domain.Category.addBlogEntry(String)

  /**
   * Removes a blog entry from this category.
   *
   * @param blogEntry   a blog entry id
   */
  public synchronized void removeBlogEntry(String blogEntry) {
    if (blogEntry != null) {
    //#category.java:389: method: void net.sourceforge.pebble.domain.Category.removeBlogEntry(String)
    //#input(void removeBlogEntry(String)): __Descendant_Table[net/sourceforge/pebble/domain/Category]
    //#input(void removeBlogEntry(String)): __Descendant_Table[others]
    //#input(void removeBlogEntry(String)): __Dispatch_Table.getParent()Lnet/sourceforge/pebble/domain/Category;
    //#input(void removeBlogEntry(String)): __Dispatch_Table.removeBlogEntry(Ljava/lang/String;)V
    //#input(void removeBlogEntry(String)): blogEntry
    //#input(void removeBlogEntry(String)): this
    //#input(void removeBlogEntry(String)): this...__Tag
    //#input(void removeBlogEntry(String)): this...blogEntries
    //#input(void removeBlogEntry(String)): this...parent
    //#input(void removeBlogEntry(String)): this.__Tag
    //#input(void removeBlogEntry(String)): this.blogEntries
    //#input(void removeBlogEntry(String)): this.parent
    //#pre[7] (void removeBlogEntry(String)): (soft) this...__Tag == net/sourceforge/pebble/domain/Category
    //#pre[8] (void removeBlogEntry(String)): (soft) this...blogEntries != null
    //#pre[9] (void removeBlogEntry(String)): (soft) init'ed(this...parent)
    //#pre[10] (void removeBlogEntry(String)): (soft) this.__Tag == net/sourceforge/pebble/domain/Category
    //#pre[11] (void removeBlogEntry(String)): (soft) this.blogEntries != null
    //#pre[12] (void removeBlogEntry(String)): (soft) init'ed(this.parent)
    //#unanalyzed(void removeBlogEntry(String)): Effects-of-calling:java.util.List:remove
    //#unanalyzed(void removeBlogEntry(String)): Effects-of-calling:removeBlogEntry
    //#test_vector(void removeBlogEntry(String)): blogEntry: Addr_Set{null}, Inverse{null}
    //#test_vector(void removeBlogEntry(String)): this.parent: Addr_Set{null}, Inverse{null}
      blogEntries.remove(blogEntry);

      if (getParent() != null) {
        getParent().removeBlogEntry(blogEntry);
      }
    }
  }
    //#category.java:396: end of method: void net.sourceforge.pebble.domain.Category.removeBlogEntry(String)

  /**
   * Removes all blog entries from this category.
   */
  public synchronized void removeAllBlogEntries() {
    blogEntries = new ArrayList<String>();
    //#category.java:402: method: void net.sourceforge.pebble.domain.Category.removeAllBlogEntries()
    //#input(void removeAllBlogEntries()): this
    //#output(void removeAllBlogEntries()): new ArrayList(removeAllBlogEntries#1) num objects
    //#output(void removeAllBlogEntries()): this.blogEntries
    //#new obj(void removeAllBlogEntries()): new ArrayList(removeAllBlogEntries#1)
    //#post(void removeAllBlogEntries()): this.blogEntries == &new ArrayList(removeAllBlogEntries#1)
    //#post(void removeAllBlogEntries()): new ArrayList(removeAllBlogEntries#1) num objects == 1
  }
    //#category.java:403: end of method: void net.sourceforge.pebble.domain.Category.removeAllBlogEntries()

  /**
   * Gets the number of blog entries associated with this category.
   *
   * @return  an int
   */
  public int getNumberOfBlogEntries() {
    return this.blogEntries.size();
    //#category.java:411: method: int net.sourceforge.pebble.domain.Category.getNumberOfBlogEntries()
    //#input(int getNumberOfBlogEntries()): this
    //#input(int getNumberOfBlogEntries()): this.blogEntries
    //#output(int getNumberOfBlogEntries()): return_value
    //#pre[2] (int getNumberOfBlogEntries()): this.blogEntries != null
    //#post(int getNumberOfBlogEntries()): init'ed(return_value)
    //#category.java:411: end of method: int net.sourceforge.pebble.domain.Category.getNumberOfBlogEntries()
  }

}
    //#category.java:: end of class: net.sourceforge.pebble.domain.Category
