class AdxPeriod {

    public static Period parse( String periodString ) 
        throws AdxException
    {
        String[] tokens = periodString.split( "/" );
        
        if ( tokens.length != 2 )
        {
            throw new AdxException( periodString + " not in valid <date>/<duration> format" );
        }

        try
        {
            Period period;
            PeriodType periodType = null;
            Date startDate = DateUtils.getMediumDate( tokens[0] );
            Calendar cal = Calendar.getInstance();
            cal.setTime( startDate );
            Duration duration = Duration.valueOf( tokens[1] );

            switch ( duration )
            {
                case P1D:
                    periodType = new DailyPeriodType();
                    break;
                case P7D:
                    periodType = new WeeklyPeriodType();
                    break;
                case P1M:
                    periodType = new MonthlyPeriodType();
                    break;
                case P2M:
                    periodType = new BiMonthlyPeriodType();
                    break;
                case P3M:
                    periodType = new QuarterlyPeriodType();
                    break;
                case P6M:
                    switch ( cal.get( Calendar.MONTH ) )
                    {
                        case 0:
                            periodType = new SixMonthlyPeriodType();
                            break;
                        case 6:
                            periodType = new SixMonthlyAprilPeriodType();
                            break;
                        default:
                            throw new AdxException( periodString + "is invalid sixmonthly type" );
                    }
                case P1Y:
                    switch ( cal.get( Calendar.MONTH ) )
                    {
                        case 0:
                            periodType = new YearlyPeriodType();
                            break;
                        case 3:
                            periodType = new FinancialAprilPeriodType();
                            break;
                        case 6:
                            periodType = new FinancialJulyPeriodType();
                            break;
                        case 9:
                            periodType = new FinancialOctoberPeriodType();
                            break;
                        default:
                            throw new AdxException( periodString + "is invalid yearly type" );
                    }
            }

            if ( periodType != null )
            {
                period = periodType.createPeriod( startDate );
            } 
            else
            {
                throw new AdxException( "Failed to create period type from " + duration );
            }

            return period;

        }
        catch ( IllegalArgumentException ex )
        {
            throw new AdxException( tokens[1] + " is not a supported duration type" );
        }
    }

}