if ( dYAxisLabelsThickness > scX.getStartShift( ) ) {  dStart = dX2 - scX.getStartShift( );
if ( scX.getDirection( ) == BACKWARD ) { if ( dYAxisLabelsThickness > scX.getEndShift( ) ) {  dEnd = dX2 - scX.getEndShift( ); } else { dEnd = scX.getEnd( ); } dStart = scX.getStart( );
	protected final double adjustHorizontal( double dBlockX, double dBlockWidth,			AllAxes aax ) throws ChartException, IllegalArgumentException	{		final OneAxis axPH = aax.areAxesSwapped( ) ? aax.getPrimaryOrthogonal( )				: aax.getPrimaryBase( );		final OneAxis axPV = aax.areAxesSwapped( ) ? aax.getPrimaryBase( )				: aax.getPrimaryOrthogonal( );		final AutoScale scX = axPH.getScale( );		final AutoScale scY = axPV.getScale( );		final int iXLabelLocation = axPH.getLabelPosition( );		final int iYLabelLocation = axPV.getLabelPosition( );		final int iYTitleLocation = axPV.getTitlePosition( );		final Label laXAxisLabels = axPH.getLabel( );		final Label laYAxisLabels = axPV.getLabel( );		final Label laYAxisTitle = axPV.getTitle( );		final int iYTickStyle = axPV.getCombinedTickStyle( );		final IntersectionValue iv = axPV.getIntersectionValue( );		// COMPUTE THE THICKNESS OF THE AXIS INCLUDING AXIS LABEL BOUNDS AND		// AXIS-PLOT SPACING		final boolean bTicksLeft = ( iYTickStyle & TICK_LEFT ) == TICK_LEFT; // 'boolean'		// FOR		// CONVENIENCE		// &		// READABILITY		final boolean bTicksRight = ( iYTickStyle & TICK_RIGHT ) == TICK_RIGHT; // 'boolean'		// FOR		// CONVENIENCE		// &		// READABILITY		final double dAppliedYAxisPlotSpacing = ( iv.iType == IntersectionValue.MAX || iv.iType == IntersectionValue.MIN ) ? dYAxisPlotSpacing				: 0;		// UPDATE Y-AXIS ENDPOINTS DUE TO AXIS LABEL SHIFTS		double dStart = scY.getStart( ), dEnd = scY.getEnd( );		scY.computeTicks( ids,				laYAxisLabels,				iYLabelLocation,				VERTICAL,				dStart,				dEnd,				true,				aax );		if ( !scY.isStepFixed( ) )		{			final Object[] oaMinMax = scY.getMinMax( );			while ( !scY.checkFit( ids, laYAxisLabels, iYLabelLocation ) )			{				if (!scY.zoomOut( ))				{					break;				}				scY.updateAxisMinMax( oaMinMax[0], oaMinMax[1] );				int tickCount = scY.computeTicks( ids,						laYAxisLabels,						iYLabelLocation,						VERTICAL,						dStart,						dEnd,						true,						aax );				if ( scY.getUnit( ) != null						&& asInteger( scY.getUnit( ) ) == Calendar.YEAR						&& tickCount <= 3 )				{					break;				}			}		}		double dYAxisLabelsThickness = scY.computeAxisLabelThickness( ids,				axPV.getLabel( ),				VERTICAL );		double dYAxisTitleThickness = 0;		if ( laYAxisTitle.isVisible( ) )		{			final String sPreviousValue = laYAxisTitle.getCaption( ).getValue( );			laYAxisTitle.getCaption( )					.setValue( rtc.externalizedMessage( sPreviousValue ) );			try			{				dYAxisTitleThickness = computeBox( ids,						iYTitleLocation,						laYAxisTitle,						0,						0 ).getWidth( );			}			catch ( IllegalArgumentException uiex )			{				throw new ChartException( ChartEnginePlugin.ID,						ChartException.GENERATION,						uiex );			}			finally			{				laYAxisTitle.getCaption( ).setValue( sPreviousValue );			}		}		double dX = getLocation( scX, iv ), dX1 = dX, dX2 = dX; // Y-AXIS BAND		// HORIZONTAL		// CO-ORDINATES		// COMPUTE VALUES FOR x1, x, x2		// x = HORIZONTAL LOCATION OF Y-AXIS ALONG PLOT		// x1 = LEFT EDGE OF Y-AXIS BAND (DUE TO AXIS LABELS, TITLE, TICKS &		// SPACING)		// x2 = RIGHT EDGE OF Y-AXIS BAND (DUE TO AXIS LABELS, TITLE, TICKS &		// SPACING)		if ( iv.iType == IntersectionValue.MIN ) // LEFT		{			// NOTE: ENSURE CODE SYMMETRY WITH 'InsersectionValue.MAX'			dX -= dAppliedYAxisPlotSpacing;			dX1 = dX;			dX2 = dX;			if ( bTicksLeft )			{				dX1 -= TICK_SIZE;			}			if ( iYLabelLocation == LEFT )			{				dX1 -= dYAxisLabelsThickness;				dX2 += Math.max( // IF LABELS ARE LEFT, THEN RIGHT SPACING IS						// MAX(RT_TICK_SIZE, HORZ_SPACING)						bTicksRight ? TICK_SIZE : 0, dAppliedYAxisPlotSpacing );			}			else if ( iYLabelLocation == RIGHT )			{				dX2 += Math.max( // IF LABELS ARE RIGHT, THEN RIGHT SPACING						// IS						// MAX(RT_TICK_SIZE+AXIS_LBL_THCKNESS,						// HORZ_SPACING)						( bTicksRight ? TICK_SIZE : 0 ) + dYAxisLabelsThickness,						dAppliedYAxisPlotSpacing );			}			if ( iYTitleLocation == LEFT )			{				dX1 -= dYAxisTitleThickness;			}			else if ( iYTitleLocation == RIGHT )			{				dX2 += dYAxisTitleThickness;			}			// ENSURE THAT WE DON'T GO BEHIND THE LEFT PLOT BLOCK EDGE			if ( dX1 < dBlockX )			{				final double dDelta = ( dBlockX - dX1 );				dX1 = dBlockX;				dX += dDelta;				dX2 += dDelta;			}			final double dDeltaX1 = dX - dX1;			final double dDeltaX2 = dX2 - dX;			// COMPUTE THE Y-AXIS BAND THICKNESS AND ADJUST X2 FOR LABELS BELOW			if ( iYLabelLocation == RIGHT )			{				// Y-AXIS BAND IS (x1 -> (x+AxisPlotSpacing))				dX2 = ( dX + dAppliedYAxisPlotSpacing );			}			dYAxisLabelsThickness = dX2 - dX1; // REUSE VARIABLE			// CHECK IF X-AXIS THICKNESS REQUIRES A PLOT HEIGHT RESIZE AT THE			// UPPER END			scX.computeAxisStartEndShifts( ids,					laXAxisLabels,					HORIZONTAL,					iXLabelLocation,					aax );			if ( dYAxisLabelsThickness > scX.getStartShift( ) )			{				// REDUCE scX's STARTPOINT TO FIT THE Y-AXIS ON THE LEFT				dStart = dX2 - scX.getStartShift( );			}			else			{				dStart = scX.getStart( );			}			dEnd = scX.getEnd( );			scX.resetShifts( );			// LOOP THAT AUTO-RESIZES Y-AXIS AND RE-COMPUTES Y-AXIS LABELS IF			// OVERLAPS OCCUR			scX.setEndPoints( dStart, dEnd );			scX.computeTicks( ids,					laXAxisLabels,					iXLabelLocation,					HORIZONTAL,					dStart,					dEnd,					true,					aax );			if ( !scX.isStepFixed( ) )			{				final Object[] oaMinMax = scX.getMinMax( );				while ( !scX.checkFit( ids, laXAxisLabels, iXLabelLocation ) )				{					if (!scX.zoomOut( ))					{						break;					}					scX.updateAxisMinMax( oaMinMax[0], oaMinMax[1] );					int tickCount = scX.computeTicks( ids,							laXAxisLabels,							iXLabelLocation,							HORIZONTAL,							dStart,							dEnd,							true,							aax );					if ( scX.getUnit( ) != null							&& asInteger( scX.getUnit( ) ) == Calendar.YEAR							&& tickCount <= 3 )					{						break;					}				}			}			// MOVE THE Y-AXIS TO THE LEFT EDGE OF THE PLOT IF SLACK SPACE			// EXISTS			if ( dYAxisLabelsThickness < scX.getStartShift( ) )			{				dX = scX.getStart( ) - ( dX2 - dX );			}			dX -= insCA.getLeft( );			dX2 = dX + dDeltaX2;			dX1 = dX - dDeltaX1;			axPV.setTitleCoordinate( ( iYTitleLocation == LEFT ) ? dX1 - 1					: dX2 + 1 - dYAxisTitleThickness );		}		else if ( iv.iType == IntersectionValue.MAX ) // RIGHT		{			// NOTE: ENSURE CODE SYMMETRY WITH 'InsersectionValue.MIN'			dX += dAppliedYAxisPlotSpacing;			dX1 = dX;			dX2 = dX;			if ( bTicksRight )			{				dX2 += TICK_SIZE;			}			if ( iYLabelLocation == RIGHT )			{				dX2 += dYAxisLabelsThickness;				dX1 -= Math.max( bTicksLeft ? TICK_SIZE : 0,						dAppliedYAxisPlotSpacing );			}			else if ( iYLabelLocation == LEFT )			{				dX1 -= Math.max( ( bTicksLeft ? TICK_SIZE : 0 )						+ dYAxisLabelsThickness, dAppliedYAxisPlotSpacing );			}			if ( iYTitleLocation == RIGHT )			{				dX2 += dYAxisTitleThickness;			}			else if ( iYTitleLocation == LEFT )			{				dX1 -= dYAxisTitleThickness;			}			// ENSURE THAT WE DON'T GO AHEAD OF THE RIGHT PLOT BLOCK EDGE			if ( dX2 > dBlockX + dBlockWidth )			{				final double dDelta = dX2 - ( dBlockX + dBlockWidth );				dX2 = dBlockX + dBlockWidth;				dX -= dDelta;				dX1 -= dDelta;			}			final double dDeltaX1 = dX - dX1;			final double dDeltaX2 = dX2 - dX;			// COMPUTE THE Y-AXIS BAND THICKNESS AND ADJUST X1 IF Y-AXIS LABELS			// ARE ON THE LEFT			if ( iYLabelLocation == LEFT )			{				// Y-AXIS BAND IS ((x-AxisPlotSpacing) -> x2)				dX1 = ( dX - dAppliedYAxisPlotSpacing );			}			dYAxisLabelsThickness = dX2 - dX1; // REUSE VARIABLE			// CHECK IF X-AXIS THICKNESS REQUIRES A PLOT HEIGHT RESIZE AT THE			// UPPER END			scX.computeAxisStartEndShifts( ids,					laXAxisLabels,					HORIZONTAL,					iXLabelLocation,					aax );			if ( dYAxisLabelsThickness > scX.getEndShift( ) )			{				// REDUCE scX's ENDPOINT TO FIT THE Y-AXIS ON THE RIGHT				dEnd = dX1 + scX.getEndShift( );			}			else			{				dEnd = scX.getEnd( );			}			dStart = scX.getStart( );			scX.resetShifts( );			// LOOP THAT AUTO-RESIZES Y-AXIS AND RE-COMPUTES Y-AXIS LABELS IF			// OVERLAPS OCCUR			scX.setEndPoints( dStart, dEnd );			scX.computeTicks( ids,					laXAxisLabels,					iXLabelLocation,					HORIZONTAL,					dStart,					dEnd,					true,					aax );			if ( !scX.isStepFixed( ) )			{				final Object[] oaMinMax = scX.getMinMax( );				while ( !scX.checkFit( ids, laXAxisLabels, iXLabelLocation ) )				{					if (!scX.zoomOut( ))					{						break;					}					scX.updateAxisMinMax( oaMinMax[0], oaMinMax[1] );					int tickCount = scX.computeTicks( ids,							laXAxisLabels,							iXLabelLocation,							HORIZONTAL,							dStart,							dEnd,							true,							aax );					if ( scX.getUnit( ) != null							&& asInteger( scX.getUnit( ) ) == Calendar.YEAR							&& tickCount <= 3 )					{						break;					}				}			}			// MOVE THE Y-AXIS TO THE LEFT EDGE OF THE PLOT IF SLACK SPACE			// EXISTS			if ( dYAxisLabelsThickness < scX.getEndShift( ) )			{				dX = scX.getEnd( ) - ( dX1 - dX );			}			dX += insCA.getRight( );			dX2 = dX + dDeltaX2;			dX1 = dX - dDeltaX1;			axPV.setTitleCoordinate( ( iYTitleLocation == LEFT ) ? dX1 - 1					: dX2 + 1 - dYAxisTitleThickness );		}		else		{			double dDeltaX1 = 0, dDeltaX2 = 0;			if ( iYTitleLocation == RIGHT )			{				dX2 += dYAxisTitleThickness;			}			else if ( iYTitleLocation == LEFT )			{				dX1 -= dYAxisTitleThickness;			}			if ( iYLabelLocation == LEFT )			{				dX1 -= ( bTicksLeft ? TICK_SIZE : 0 ) + dYAxisLabelsThickness;				dX2 += ( bTicksRight ? TICK_SIZE : 0 );				dDeltaX1 = dX - dX1;				dDeltaX2 = dX2 - dX;				// CHECK IF LEFT EDGE OF Y-AXIS BAND GOES BEHIND THE PLOT LEFT				// EDGE				if ( dX1 < dBlockX )				{					final Object[] oaMinMax = scX.getMinMax( );					boolean bForceBreak = false;					// A LOOP THAT ITERATIVELY ATTEMPTS TO ADJUST THE LEFT EDGE					// OF THE Y-AXIS LABELS WITH THE LEFT EDGE OF THE PLOT					// AND/OR					// ENSURE THAT THE START POINT OF THE X-AXIS SCALE IS					// SUITABLY POSITIONED					// computeTicks(g2d, fm, iXLabelLocation, iXRotation,					// HORIZONTAL, scX.dStart, scX.dEnd, scX, true);					do					{						// CANCEL OUT THE ENDPOINT LABEL SHIFT COMPUTATIONS FROM						// THE X-AXIS						scX.setEndPoints( scX.getStart( ) - scX.getStartShift( ),								scX.getEnd( ) + scX.getEndShift( ) ); // RESTORE						scX.resetShifts( );						// APPLY THE AXIS REDUCTION FORMULA W.R.T. X-AXIS						// STARTPOINT						double[] da = scX.getEndPoints( );						double dT_RI = dBlockX - dX1; // THRESHOLD -						// REQUESTEDINTERSECTION						double dAMin_AMax = da[1] - da[0];						double dAMax_RI = da[1] - dX;						double dDelta = ( dT_RI / dAMax_RI ) * dAMin_AMax;						dStart = da[0] + dDelta;						dEnd = da[1];						if ( dStart < dBlockX )						{							dStart = dBlockX;							bForceBreak = true; // ADJUST THE TOP EDGE OF THE							// Y-AXIS SCALE TO THE TOP EDGE							// OF THE PLOT BLOCK						}						// LOOP THAT AUTO-RESIZES Y-AXIS AND RE-COMPUTES Y-AXIS						// LABELS IF OVERLAPS OCCUR						scX.setEndPoints( dStart, dEnd );						scX.computeTicks( ids,								laXAxisLabels,								iXLabelLocation,								HORIZONTAL,								dStart,								dEnd,								true,								aax );						while ( !scX.checkFit( ids,								laXAxisLabels,								iXLabelLocation ) )						{							if (!scX.zoomOut( ))							{								bForceBreak = true;								break;							}							scX.updateAxisMinMax( oaMinMax[0], oaMinMax[1] );							int tickCount = scX.computeTicks( ids,									laXAxisLabels,									iXLabelLocation,									HORIZONTAL,									dStart,									dEnd,									true,									aax );							if ( scX.getUnit( ) != null									&& asInteger( scX.getUnit( ) ) == Calendar.YEAR									&& tickCount <= 3 )							{								bForceBreak = true;								break;							}						}						dX = getLocation( scX, iv );						dX1 = dX - dDeltaX1; // RE-CALCULATE X-AXIS BAND LEFT						// EDGE					} while ( Math.abs( dX1 - dBlockX ) > 1 && !bForceBreak );				}				else				{					// LOOP THAT AUTO-RESIZES Y-AXIS AND RE-COMPUTES Y-AXIS					// LABELS IF OVERLAPS OCCUR					dStart = scX.getStart( );					dEnd = scX.getEnd( );					scX.setEndPoints( dStart, dEnd );					scX.computeTicks( ids,							laXAxisLabels,							iXLabelLocation,							HORIZONTAL,							dStart,							dEnd,							true,							aax );					if ( !scX.isStepFixed( ) )					{						final Object[] oaMinMax = scX.getMinMax( );						while ( !scX.checkFit( ids,								laXAxisLabels,								iXLabelLocation ) )						{							if (!scX.zoomOut( ))							{								break;							}							scX.updateAxisMinMax( oaMinMax[0], oaMinMax[1] );							int tickCount = scX.computeTicks( ids,									laXAxisLabels,									iXLabelLocation,									HORIZONTAL,									dStart,									dEnd,									true,									aax );							if ( scX.getUnit( ) != null									&& asInteger( scX.getUnit( ) ) == Calendar.YEAR									&& tickCount <= 3 )							{								break;							}						}					}					dX = getLocation( scX, iv );				}				dX1 = dX - dDeltaX1;				dX2 = dX + dDeltaX2;			}			else if ( iYLabelLocation == RIGHT )			{				dX2 += ( bTicksRight ? TICK_SIZE : 0 ) + dYAxisLabelsThickness;				dX1 -= ( bTicksLeft ? TICK_SIZE : 0 );				dDeltaX1 = dX - dX1;				dDeltaX2 = dX2 - dX;				// CHECK IF RIGHT EDGE OF Y-AXIS BAND GOES BEHIND THE PLOT RIGHT				// EDGE				if ( dX2 > dBlockX + dBlockWidth )				{					final Object[] oaMinMax = scX.getMinMax( );					boolean bForceBreak = false;					// A LOOP THAT ITERATIVELY ATTEMPTS TO ADJUST THE RIGHT EDGE					// OF THE Y-AXIS LABELS WITH THE RIGHT EDGE OF THE PLOT					// AND/OR					// ENSURE THAT THE START POINT OF THE X-AXIS SCALE IS					// SUITABLY POSITIONED					do					{						// CANCEL OUT THE ENDPOINT LABEL SHIFT COMPUTATIONS FROM						// THE X-AXIS						scX.setEndPoints( scX.getStart( ) - scX.getStartShift( ),								scX.getEnd( ) + scX.getEndShift( ) ); // RESTORE						scX.resetShifts( );						// APPLY THE AXIS REDUCTION FORMULA W.R.T. X-AXIS						// ENDPOINT						double[] da = scX.getEndPoints( );						double dT_RI = dX2 - ( dBlockX + dBlockWidth ); // THRESHOLD						// -						// REQUESTEDINTERSECTION						double dAMin_AMax = da[1] - da[0];						double dAMin_RI = dX - da[0];						double dDelta = ( dT_RI / dAMin_RI ) * dAMin_AMax;						dEnd = da[1] - dDelta;						dStart = da[0];						if ( dEnd > dBlockX + dBlockWidth )						{							dEnd = dBlockX + dBlockWidth;							bForceBreak = true; // ADJUST THE TOP EDGE OF THE							// Y-AXIS SCALE TO THE TOP EDGE							// OF THE PLOT BLOCK						}						// LOOP THAT AUTO-RESIZES Y-AXIS AND RE-COMPUTES Y-AXIS						// LABELS IF OVERLAPS OCCUR						scX.setEndPoints( dStart, dEnd );						scX.computeTicks( ids,								laXAxisLabels,								iXLabelLocation,								HORIZONTAL,								dStart,								dEnd,								true,								aax );						if ( !scX.isStepFixed( ) )						{							while ( !scX.checkFit( ids,									laXAxisLabels,									iXLabelLocation ) )							{								if (!scX.zoomOut( ))								{									bForceBreak = true;									break;								}								scX.updateAxisMinMax( oaMinMax[0], oaMinMax[1] );								int tickCount = scX.computeTicks( ids,										laXAxisLabels,										iXLabelLocation,										HORIZONTAL,										dStart,										dEnd,										true,										aax );								if ( scX.getUnit( ) != null										&& asInteger( scX.getUnit( ) ) == Calendar.YEAR										&& tickCount <= 3 )								{									bForceBreak = true;									break;								}							}						}						dX = getLocation( scX, iv );						dX2 = dX + dDeltaX2; // RE-CALCULATE X-AXIS BAND						// RIGHT						// EDGE					} while ( Math.abs( dX2 - ( dBlockX + dBlockWidth ) ) > 1							&& !bForceBreak );				}				else				{					// LOOP THAT AUTO-RESIZES Y-AXIS AND RE-COMPUTES Y-AXIS					// LABELS IF OVERLAPS OCCUR					dStart = scX.getStart( );					dEnd = scX.getEnd( );					scX.setEndPoints( dStart, dEnd );					scX.computeTicks( ids,							laXAxisLabels,							iXLabelLocation,							HORIZONTAL,							dStart,							dEnd,							true,							aax );					if ( !scX.isStepFixed( ) )					{						final Object[] oaMinMax = scX.getMinMax( );						while ( !scX.checkFit( ids,								laXAxisLabels,								iXLabelLocation ) )						{							if (!scX.zoomOut( ))							{								break;							}							scX.updateAxisMinMax( oaMinMax[0], oaMinMax[1] );							int tickCount = scX.computeTicks( ids,									laXAxisLabels,									iXLabelLocation,									HORIZONTAL,									dStart,									dEnd,									true,									aax );							if ( scX.getUnit( ) != null									&& asInteger( scX.getUnit( ) ) == Calendar.YEAR									&& tickCount <= 3 )							{								break;							}						}					}					dX = getLocation( scX, iv );				}				dX2 = dX + dDeltaX2;				dX1 = dX - dDeltaX1;			}			axPV.setTitleCoordinate( ( iYTitleLocation == LEFT ) ? dX1 - 1					: dX2 + 1 - dYAxisTitleThickness );		}		return dX;	}