Generics Java

//package org.hh.jga.util;
import java.io.Serializable;
/**
 * Simple STL Pair Implementation
 * 
 * @author Hong Hong
 *
 * @param  the type of first element
 * @param  the type of second element
 */
public class Pair implements Serializable {
  private static final long serialVersionUID = -312111942211427434L;
  public E1 first;
  public E2 second;
  
  /**
   * This is a comparable pair
   * 
   * @author Hong Hong
   *
   * @param  the type of first element
   * @param  the type of second element
   */
  public static class CpPair, E2 extends Comparable> extends Pair implements Comparable> {
    private static final long serialVersionUID = -6710234564965065727L;
    public int compareTo(CpPair o) {
      int res = first != null ? first.compareTo(o.first) : (o.first != null ? -1 : 0);
      if(res == 0)
        res = second != null ? second.compareTo(o.second) : (o.second != null ? -1 : 0);
      return res;
    }
    public CpPair(E1 first, E2 second) {
      this.first = first;
      this.second = second;
    }
    public CpPair() {
    }
    public > CpPair> frontAppend(E e) {
      return make_pair(e, this);
    }
  }
  public static  Pair make_pair(E1 e1, E2 e2) {
    return new Pair(e1, e2);
  }
  public static , E2 extends Comparable> CpPair make_pair(E1 e1, E2 e2) {
    return new CpPair(e1, e2);
  }
  public static  Pair> make_chain(E1 e1, E2 e2, E3 e3) {
    return new Pair>(e1, new Pair(e2, e3));
  }
  public static , E2 extends Comparable, E3 extends Comparable
  CpPair> make_chain(E1 e1, E2 e2, E3 e3) {
    return make_pair(e1, make_pair(e2, e3));
  }
  
  public  Pair> frontAppend(E e) {
    return make_pair(e, this);
  }
  
  
  public Pair(E1 first, E2 second) {
    this.first = first;
    this.second = second;
  }
  public Pair() {
  }
  
  public int hashCode() {
    return (first == null ? 0 : first.hashCode())
      ^ (second == null ? 0 : second.hashCode());
  }
  
  @SuppressWarnings("unchecked")
  public boolean equals(Object other) {
    if(other.getClass().equals(getClass())) {
      Pair o = (Pair) other;
      if(first == o.first || first != null && first.equals(o.first)) {
        if(second == o.second || second != null && second.equals(o.second))
          return true;
      }
    }
    return false;
  }
  
  public String toString() {
    return "Pair(" + first.toString() + ", " + second.toString() + ")";
  }
}